tescmd 0.3.1__py3-none-any.whl → 0.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,543 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: tescmd
3
- Version: 0.3.1
4
- Summary: A Python CLI for querying and controlling Tesla vehicles via the Fleet API
5
- Project-URL: Homepage, https://github.com/oceanswave/tescmd
6
- Project-URL: Repository, https://github.com/oceanswave/tescmd
7
- Project-URL: Issues, https://github.com/oceanswave/tescmd/issues
8
- Project-URL: Documentation, https://github.com/oceanswave/tescmd#readme
9
- Author: oceanswave
10
- License-Expression: MIT
11
- License-File: LICENSE
12
- Keywords: cli,ev,fleet-api,tesla,vehicle
13
- Classifier: Development Status :: 4 - Beta
14
- Classifier: Environment :: Console
15
- Classifier: Intended Audience :: Developers
16
- Classifier: License :: OSI Approved :: MIT License
17
- Classifier: Operating System :: OS Independent
18
- Classifier: Programming Language :: Python :: 3
19
- Classifier: Programming Language :: Python :: 3.11
20
- Classifier: Programming Language :: Python :: 3.12
21
- Classifier: Programming Language :: Python :: 3.13
22
- Classifier: Topic :: Software Development :: Libraries
23
- Classifier: Typing :: Typed
24
- Requires-Python: >=3.11
25
- Requires-Dist: click>=8.1
26
- Requires-Dist: cryptography>=42.0
27
- Requires-Dist: httpx>=0.27
28
- Requires-Dist: keyring>=25.0
29
- Requires-Dist: mcp>=1.0
30
- Requires-Dist: protobuf>=5.29
31
- Requires-Dist: pydantic-settings>=2.0
32
- Requires-Dist: pydantic>=2.0
33
- Requires-Dist: python-dotenv>=1.0
34
- Requires-Dist: rich>=13.0
35
- Requires-Dist: starlette>=0.37
36
- Requires-Dist: textual>=1.0
37
- Requires-Dist: uvicorn>=0.30
38
- Requires-Dist: websockets>=14.0
39
- Provides-Extra: ble
40
- Requires-Dist: bleak>=0.22; extra == 'ble'
41
- Provides-Extra: dev
42
- Requires-Dist: build>=1.0; extra == 'dev'
43
- Requires-Dist: grpcio-tools>=1.68; extra == 'dev'
44
- Requires-Dist: mypy-protobuf>=3.6; extra == 'dev'
45
- Requires-Dist: mypy>=1.13; extra == 'dev'
46
- Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
47
- Requires-Dist: pytest-cov>=5.0; extra == 'dev'
48
- Requires-Dist: pytest-httpx>=0.34; extra == 'dev'
49
- Requires-Dist: pytest-xdist>=3.0; extra == 'dev'
50
- Requires-Dist: pytest>=8.0; extra == 'dev'
51
- Requires-Dist: ruff>=0.8; extra == 'dev'
52
- Description-Content-Type: text/markdown
53
-
54
- <p align="center">
55
- <img src="images/tescmd_header.jpeg" alt="tescmd — Python CLI for Tesla Fleet API" width="100%">
56
- </p>
57
-
58
- # tescmd
59
-
60
- <p align="center">
61
- <a href="https://pypi.org/project/tescmd/"><img src="https://img.shields.io/pypi/v/tescmd" alt="PyPI"></a>
62
- <a href="https://pypi.org/project/tescmd/"><img src="https://img.shields.io/pypi/pyversions/tescmd" alt="Python"></a>
63
- <a href="https://github.com/oceanswave/tescmd/actions/workflows/test.yml"><img src="https://img.shields.io/github/actions/workflow/status/oceanswave/tescmd/test.yml?branch=main&label=build" alt="Build"></a>
64
- <a href="LICENSE"><img src="https://img.shields.io/github/license/oceanswave/tescmd" alt="License"></a>
65
- <a href="https://github.com/oceanswave/tescmd/releases"><img src="https://img.shields.io/github/v/release/oceanswave/tescmd" alt="GitHub Release"></a>
66
- </p>
67
-
68
- A Python CLI for querying and controlling Tesla vehicles via the Fleet API — built for both human operators and AI agents.
69
-
70
- ## What It Does
71
-
72
- tescmd gives you full command-line access to Tesla's Fleet API: check battery and charge status, lock or unlock doors, control climate, open trunks, send navigation waypoints, manage Powerwalls, stream live telemetry, and more. It handles OAuth2 authentication, token refresh, key enrollment, command signing, and response caching so you don't have to. Every command works in both interactive (Rich tables) and scripted (JSON) modes, and an MCP server lets AI agents call any command as a tool.
73
-
74
- ## Why tescmd?
75
-
76
- Tesla's Fleet API gives developers full access to vehicle data and commands, but working with it directly means juggling OAuth2 PKCE flows, token refresh, regional endpoints, key enrollment, and raw JSON responses.
77
-
78
- tescmd wraps all of that into a single command-line tool that handles authentication, token management, and output formatting so you can focus on what you actually want to do — check your battery, find your car, or control your vehicle.
79
-
80
- tescmd is designed to work as a tool that AI agents can invoke directly. Platforms like [OpenClaw](https://openclaw.ai/), [Claude Desktop](https://claude.ai), and other agent frameworks can call tescmd commands, parse the structured JSON output, and take actions on your behalf — "lock my car", "what's my battery at?", "start climate control". The deterministic JSON output, meaningful exit codes, cost-aware wake confirmation, and `--wake` opt-in flag make it safe for autonomous agent use without surprise billing.
81
-
82
- ## Features
83
-
84
- - **Vehicle state queries** — battery, range, charge status, climate, location, doors, windows, trunks, tire pressure, dashcam, sentry mode, and more
85
- - **Vehicle commands** — charge start/stop/limit/departure scheduling, climate on/off/set temp/seats/steering wheel, lock/unlock, sentry mode, trunk/frunk, windows, HomeLink, navigation waypoints, media playback, speed limits, PIN management
86
- - **Vehicle Command Protocol** — ECDH session management with HMAC-SHA256 signed commands via the `signed_command` endpoint; automatically used when keys are enrolled
87
- - **Key enrollment** — `tescmd key enroll <VIN>` sends your public key to the vehicle and guides you through Tesla app approval
88
- - **Tier enforcement** — readonly tier blocks write commands with clear guidance to upgrade
89
- - **Energy products** — Powerwall live status, site info, backup reserve, operation mode, storm mode, time-of-use settings, charging history, calendar history, grid import/export
90
- - **User & sharing** — account info, region, orders, feature flags, driver management, vehicle sharing invites
91
- - **Live Dashboard** — `tescmd serve` launches a full-screen TUI showing live telemetry data, MCP server info, tunnel URL, sink count, and cache stats — all in a scrollable, interactive terminal UI powered by Textual
92
- - **Fleet Telemetry streaming** — `tescmd serve` (or `tescmd vehicle telemetry stream`) receives push-based data from your vehicle via Tailscale Funnel — no polling, 99%+ cost reduction. Telemetry sessions produce a wide-format CSV log by default
93
- - **OpenClaw Bridge** — `tescmd serve --openclaw ws://...` streams filtered telemetry to an OpenClaw Gateway with configurable delta+throttle filtering per field; supports bidirectional command dispatch so bots can send vehicle commands back through the gateway
94
- - **Trigger subscriptions** — register conditions on any telemetry field (battery < 20%, speed > 80, location enters geofence) and get notified via OpenClaw push events or MCP polling; supports one-shot and persistent modes with cooldown
95
- - **MCP Server** — `tescmd serve` (or `tescmd mcp serve`) exposes all commands as MCP tools for Claude.ai, Claude Desktop, Claude Code, and other agent frameworks via OAuth 2.1
96
- - **Universal response caching** — all read commands are cached with tiered TTLs (1h for specs/warranty, 5m for fleet lists, 1m standard, 30s for location-dependent); bots can call tescmd as often as needed — within the TTL window, responses are instant and free
97
- - **Cost-aware wake** — prompts before sending billable wake API calls; `--wake` flag for scripts that accept the cost
98
- - **Guided OAuth2 setup** — `tescmd auth login` walks you through browser-based authentication with PKCE
99
- - **Key management** — generate EC keys, register via Tesla Developer Portal (remote) or BLE enrollment (proximity)
100
- - **Rich terminal output** — tables, panels, spinners powered by Rich; auto-detects TTY vs pipe
101
- - **Configurable display units** — switch between PSI/bar, °F/°C, and mi/km (defaults to US units)
102
- - **JSON output** — structured output for scripting and agent integration
103
- - **Multi-profile** — switch between vehicles, accounts, and regions with named profiles
104
- - **Agent-friendly** — deterministic JSON, meaningful exit codes, `--wake` opt-in, headless auth support
105
-
106
- ## Quick Start
107
-
108
- ```bash
109
- pip install tescmd
110
- tescmd setup
111
- ```
112
-
113
- That's it. The interactive setup wizard walks you through everything: creating a Tesla Developer app, generating an EC key pair, hosting the public key (via GitHub Pages or Tailscale Funnel), registering with the Fleet API, authenticating via OAuth2, and enrolling your key on a vehicle. Each step checks prerequisites and offers remediation if something is missing.
114
-
115
- After setup completes, you can start using commands:
116
-
117
- ```bash
118
- tescmd charge status # Check battery and charging state
119
- tescmd vehicle info # Full vehicle data snapshot
120
- tescmd climate on --wake # Turn on climate (wakes vehicle if asleep)
121
- tescmd security lock --wake # Lock the car
122
- tescmd serve 5YJ3... # MCP + telemetry TUI dashboard + CSV log
123
- tescmd serve --no-mcp # Telemetry-only TUI dashboard
124
- ```
125
-
126
- Every read command is cached — repeat calls within the TTL window are instant and free.
127
-
128
- ## Prerequisites
129
-
130
- | Requirement | Required | What it is | Why tescmd needs it |
131
- |---|---|---|---|
132
- | **Python 3.11+** | Yes | The programming language runtime that runs tescmd | tescmd is a Python package — you need Python installed to use it |
133
- | **pip** | Yes | Python's package installer (ships with Python) | Used to install tescmd and its dependencies via `pip install tescmd` |
134
- | **Tesla account** | Yes | A [tesla.com](https://www.tesla.com) account linked to a vehicle or energy product | tescmd authenticates via OAuth2 against your Tesla account to access the Fleet API |
135
- | **Git** | Yes | Version control tool ([git-scm.com](https://git-scm.com)) | Used during setup for key hosting via GitHub Pages |
136
- | **GitHub CLI** (`gh`) | Recommended | GitHub's command-line tool ([cli.github.com](https://cli.github.com)) — authenticate with `gh auth login` | Auto-creates a `*.github.io` site to host your public key at the `.well-known` path Tesla requires |
137
- | **Tailscale** | Recommended | Mesh VPN with public tunneling ([tailscale.com](https://tailscale.com)) — authenticate with `tailscale login` | Provides a public HTTPS URL for key hosting and Fleet Telemetry streaming with zero infrastructure setup |
138
-
139
- ### Self-Hosting with Tailscale (No Domain Required)
140
-
141
- If you have **Tailscale** installed with Funnel enabled, you don't need a custom domain or GitHub Pages at all. Tailscale Funnel gives you a public HTTPS URL (`<machine>.tailnet.ts.net`) that serves both your public key and (optionally) Fleet Telemetry streaming — all from your local machine with zero infrastructure setup.
142
-
143
- ```bash
144
- # Install Tailscale, enable Funnel in your tailnet ACL, then:
145
- tescmd setup # wizard auto-detects Tailscale and offers it as the hosting method
146
- ```
147
-
148
- This is the fastest path to a working setup: Tailscale handles TLS certificates, NAT traversal, and public DNS automatically. The tradeoff is that your machine needs to be running for Tesla to reach your key and for telemetry streaming to work. For always-on key hosting with offline machines, use GitHub Pages instead.
149
-
150
- Without either GitHub CLI or Tailscale, you'll need to manually host your public key at the Tesla-required `.well-known` path on your own domain.
151
-
152
- ## Installation
153
-
154
- ### From PyPI
155
-
156
- ```bash
157
- pip install tescmd
158
- ```
159
-
160
- ### From Source
161
-
162
- ```bash
163
- git clone https://github.com/oceanswave/tescmd.git
164
- cd tescmd
165
- pip install -e ".[dev]"
166
- ```
167
-
168
- ## Configuration
169
-
170
- tescmd resolves settings in this order (highest priority first):
171
-
172
- 1. **CLI arguments** — `--vin`, `--region`, `--format`, `--units`, etc.
173
- 2. **Environment variables** — `TESLA_VIN`, `TESLA_REGION`, etc. (`.env` files loaded automatically)
174
- 3. **Defaults**
175
-
176
- ### Environment Variables
177
-
178
- Create a `.env` file in your working directory or `~/.config/tescmd/.env`:
179
-
180
- ```dotenv
181
- TESLA_CLIENT_ID=your-client-id
182
- TESLA_CLIENT_SECRET=your-client-secret
183
- TESLA_VIN=5YJ3E1EA1NF000000
184
- TESLA_REGION=na
185
-
186
- # Token storage (optional — defaults to OS keyring with file fallback)
187
- TESLA_TOKEN_FILE=~/.config/tescmd/tokens.json
188
-
189
- # Cache settings (optional)
190
- TESLA_CACHE_ENABLED=true
191
- TESLA_CACHE_TTL=60
192
- TESLA_CACHE_DIR=~/.cache/tescmd
193
-
194
- # Command protocol: auto | signed | unsigned (optional)
195
- TESLA_COMMAND_PROTOCOL=auto
196
-
197
- # Display units (optional — defaults to US units)
198
- TESLA_TEMP_UNIT=F # F or C
199
- TESLA_DISTANCE_UNIT=mi # mi or km
200
- TESLA_PRESSURE_UNIT=psi # psi or bar
201
- ```
202
-
203
- ## Token Storage
204
-
205
- By default, tescmd stores OAuth tokens in the OS keyring (macOS Keychain, GNOME Keyring, Windows Credential Manager). On headless systems where no keyring daemon is available (Docker, CI, SSH sessions), tescmd automatically falls back to a file-based store at `~/.config/tescmd/tokens.json` with restricted permissions (`0600` on Unix, owner-only ACL on Windows).
206
-
207
- You can force file-based storage by setting `TESLA_TOKEN_FILE`:
208
-
209
- ```bash
210
- export TESLA_TOKEN_FILE=~/.config/tescmd/tokens.json
211
- ```
212
-
213
- To transfer tokens between machines, use `auth export` and `auth import`:
214
-
215
- ```bash
216
- # On source machine
217
- tescmd auth export > tokens.json
218
-
219
- # On target machine (Docker, CI, etc.)
220
- tescmd auth import < tokens.json
221
- ```
222
-
223
- Check which backend is active with `tescmd status` — the output includes a `Token store` line showing `keyring` or the file path.
224
-
225
- > **Security note:** File-based tokens are stored as plaintext JSON. The file is created with owner-only permissions, but treat it like any other credential file.
226
-
227
- ## Commands
228
-
229
- | Group | Commands | Description |
230
- |---|---|---|
231
- | `setup` | *(interactive wizard)* | First-run configuration: client ID, secret, region, domain, key enrollment |
232
- | `auth` | `login`, `logout`, `status`, `refresh`, `register`, `export`, `import` | OAuth2 authentication lifecycle |
233
- | `vehicle` | `list`, `get`, `info`, `data`, `location`, `wake`, `rename`, `mobile-access`, `nearby-chargers`, `alerts`, `release-notes`, `service`, `drivers`, `calendar`, `subscriptions`, `upgrades`, `options`, `specs`, `warranty`, `fleet-status`, `low-power`, `accessory-power`, `telemetry {config,create,delete,errors,stream}` | Vehicle discovery, state queries, fleet telemetry streaming, power management |
234
- | `charge` | `status`, `start`, `stop`, `limit`, `limit-max`, `limit-std`, `amps`, `port-open`, `port-close`, `schedule`, `departure`, `precondition-add`, `precondition-remove`, `add-schedule`, `remove-schedule`, `clear-schedules`, `clear-preconditions`, `managed-amps`, `managed-location`, `managed-schedule` | Charge queries, control, scheduling, and fleet management |
235
- | `billing` | `history`, `sessions`, `invoice` | Supercharger billing history and invoices |
236
- | `climate` | `status`, `on`, `off`, `set`, `precondition`, `seat`, `seat-cool`, `wheel-heater`, `overheat`, `bioweapon`, `keeper`, `cop-temp`, `auto-seat`, `auto-wheel`, `wheel-level` | Climate, seat, and steering wheel control |
237
- | `security` | `status`, `lock`, `auto-secure`, `unlock`, `sentry`, `valet`, `valet-reset`, `remote-start`, `flash`, `honk`, `boombox`, `speed-limit`, `pin-to-drive`, `pin-reset`, `pin-clear-admin`, `speed-clear`, `speed-clear-admin`, `guest-mode`, `erase-data` | Security, access, and PIN management |
238
- | `trunk` | `open`, `close`, `frunk`, `window`, `sunroof`, `tonneau-open`, `tonneau-close`, `tonneau-stop` | Trunk, frunk, sunroof, tonneau, and window control |
239
- | `media` | `play-pause`, `next-track`, `prev-track`, `next-fav`, `prev-fav`, `volume-up`, `volume-down`, `adjust-volume` | Media playback control |
240
- | `nav` | `send`, `gps`, `supercharger`, `homelink`, `waypoints` | Navigation and HomeLink |
241
- | `software` | `status`, `schedule`, `cancel` | Software update management |
242
- | `energy` | `list`, `status`, `live`, `backup`, `mode`, `storm`, `tou`, `history`, `off-grid`, `grid-config`, `telemetry`, `calendar` | Energy product (Powerwall) management |
243
- | `user` | `me`, `region`, `orders`, `features` | User account information |
244
- | `sharing` | `add-driver`, `remove-driver`, `create-invite`, `redeem-invite`, `revoke-invite`, `list-invites` | Vehicle sharing and driver management |
245
- | `key` | `generate`, `deploy`, `validate`, `show`, `enroll`, `unenroll` | Key management and enrollment |
246
- | `partner` | `public-key`, `telemetry-error-vins`, `telemetry-errors` | Partner account endpoints (require client credentials) |
247
- | `serve` | *(unified server)* | Combined MCP + telemetry + OpenClaw TUI dashboard with trigger subscriptions |
248
- | `openclaw` | `bridge` | Standalone OpenClaw bridge with bidirectional command dispatch |
249
- | `mcp` | `serve` | Standalone MCP server exposing all commands as agent tools |
250
- | `cache` | `status`, `clear` | Response cache management |
251
- | `raw` | `get`, `post` | Arbitrary Fleet API endpoint access |
252
-
253
- Use `tescmd <group> --help` for detailed usage on any command group. For API endpoints not yet covered by a dedicated command, use `raw get` or `raw post` as an escape hatch.
254
-
255
- ### Global Flags
256
-
257
- These flags can be placed at the root level or after any subcommand:
258
-
259
- | Flag | Description |
260
- |---|---|
261
- | `--vin VIN` | Vehicle VIN (also accepted as a positional argument) |
262
- | `--profile NAME` | Config profile name |
263
- | `--format {rich,json,quiet}` | Force output format |
264
- | `--quiet` | Suppress normal output |
265
- | `--region {na,eu,cn}` | Tesla API region |
266
- | `--verbose` | Enable verbose logging |
267
- | `--no-cache` / `--fresh` | Bypass response cache for this invocation |
268
- | `--wake` | Auto-wake vehicle without confirmation (billable) |
269
-
270
- ## Output Formats
271
-
272
- tescmd auto-detects the best output format:
273
-
274
- - **Rich** (default in TTY) — formatted tables, panels, colored status indicators
275
- - **JSON** (`--format json` or piped) — structured, parseable output
276
- - **Quiet** (`--quiet`) — minimal output on stderr, suitable for scripts that only check exit codes
277
-
278
- ```bash
279
- # Human-friendly output
280
- tescmd vehicle list
281
-
282
- # JSON for scripting
283
- tescmd vehicle list --format json
284
-
285
- # Pipe-friendly (auto-switches to JSON)
286
- tescmd vehicle list | jq '.[0].vin'
287
-
288
- # Quiet mode (exit code only)
289
- tescmd vehicle wake --quiet && echo "Vehicle is awake"
290
- ```
291
-
292
- ### Display Units
293
-
294
- Rich output displays values in US units by default (°F, miles, PSI). Switch to metric with a single flag:
295
-
296
- ```bash
297
- tescmd --units metric charge status # All metric: °C, km, bar
298
- tescmd --units us charge status # All US: °F, mi, psi (default)
299
- ```
300
-
301
- Or configure individual units via environment variables:
302
-
303
- ```dotenv
304
- TESLA_TEMP_UNIT=C # F or C
305
- TESLA_DISTANCE_UNIT=km # mi or km
306
- TESLA_PRESSURE_UNIT=bar # psi or bar
307
- ```
308
-
309
- | Dimension | US (default) | Metric | Env Variable |
310
- |---|---|---|---|
311
- | Temperature | °F | °C | `TESLA_TEMP_UNIT` |
312
- | Distance | mi | km | `TESLA_DISTANCE_UNIT` |
313
- | Pressure | psi | bar | `TESLA_PRESSURE_UNIT` |
314
-
315
- The `--units` flag overrides all three env vars at once. The Tesla API returns Celsius, miles, and bar — conversions happen in the display layer only.
316
-
317
- ## Tesla Fleet API Costs
318
-
319
- Tesla's Fleet API is **pay-per-use** — every request returning a status code below 500 is billable, including 4xx errors like "vehicle asleep" (408) and rate limits (429). Wake requests are the most expensive category and are rate-limited to 3/min. There is no free tier (the $10/month credit is being discontinued).
320
-
321
- > **Official pricing:** [Tesla Fleet API — Billing and Limits](https://developer.tesla.com/docs/fleet-api/billing-and-limits)
322
-
323
- ### Why This Matters
324
-
325
- A naive script that polls `vehicle_data` every 5 minutes generates **4-5 billable requests per check** (asleep error + wake + poll + data fetch). That's **1,000+ billable requests per day** from a single cron job. At roughly $1 per 500 data requests, monitoring one vehicle costs around $60/month before you even count wake requests (the most expensive tier).
326
-
327
- ### Cost Example: Battery Check
328
-
329
- | | Without tescmd | With tescmd |
330
- |---|---|---|
331
- | Vehicle asleep, check battery | 408 error (billable) + wake (billable) + poll (billable) + data (billable) = **4+ requests** | Data attempt → 408 (billable) → prompt user → user wakes via Tesla app (free) → retry → data (billable) = **2 requests** |
332
- | Check battery again 30s later | Another 4+ requests | **0 requests** (cache hit) |
333
- | 10 checks in 1 minute | **40+ billable requests** | **1 billable request** + 9 cache hits |
334
-
335
- ### How tescmd Reduces Costs
336
-
337
- tescmd implements four layers of cost protection:
338
-
339
- 1. **Universal read-command cache** — **all** read commands are cached with tiered TTLs: static data (specs, warranty) cached for 1 hour, fleet lists for 5 minutes, standard queries for 1 minute, location-dependent data for 30 seconds. Bots can call tescmd as often as needed — within the TTL, responses are instant and free.
340
- 2. **Smart wake state** — Tracks whether the vehicle was recently confirmed online (30s TTL). Skips redundant wake attempts.
341
- 3. **Wake confirmation prompt** — Prompts before sending billable wake calls in interactive mode. JSON/piped mode returns a structured error with `--wake` guidance.
342
- 4. **Write-command invalidation** — write commands automatically invalidate the relevant cache scope (vehicle or energy site) so subsequent reads reflect the new state.
343
-
344
- ```bash
345
- # First call: hits API, caches response
346
- tescmd charge status
347
-
348
- # Second call within 60s: instant cache hit, no API call
349
- tescmd charge status
350
-
351
- # All read commands are cached — even vehicle list, user info, billing, etc.
352
- tescmd vehicle list # cached 5 min
353
- tescmd user me # cached 1 hour
354
- tescmd vehicle specs # cached 1 hour
355
- tescmd billing history # cached 1 min
356
-
357
- # Bypass cache when you need fresh data
358
- tescmd charge status --fresh
359
-
360
- # Auto-wake without prompting (for scripts accepting the cost)
361
- tescmd charge status --wake
362
-
363
- # Manage cache
364
- tescmd cache status # entry counts, disk usage
365
- tescmd cache clear # clear all
366
- tescmd cache clear --vin VIN # clear for one vehicle
367
- tescmd cache clear --site 12345 # clear for an energy site
368
- tescmd cache clear --scope account # clear account-level entries
369
- ```
370
-
371
- For the full cost breakdown with more examples, savings calculations, and Fleet Telemetry streaming comparison, see [docs/api-costs.md](docs/api-costs.md).
372
-
373
- Configure via environment variables:
374
-
375
- | Variable | Default | Description |
376
- |---|---|---|
377
- | `TESLA_CACHE_ENABLED` | `true` | Enable/disable the cache |
378
- | `TESLA_CACHE_TTL` | `60` | Time-to-live in seconds |
379
- | `TESLA_CACHE_DIR` | `~/.cache/tescmd` | Cache directory path |
380
-
381
- ## Fleet Telemetry Streaming
382
-
383
- Tesla's Fleet Telemetry lets your vehicle push real-time data directly to your server — no polling, no per-request charges. tescmd handles all the setup:
384
-
385
- ```bash
386
- # Full-screen TUI with live telemetry + MCP server
387
- tescmd serve 5YJ3...
388
-
389
- # Telemetry-only mode (full-screen TUI, no MCP)
390
- tescmd serve 5YJ3... --no-mcp
391
-
392
- # Select field presets
393
- tescmd serve 5YJ3... --fields driving # Speed, location, power
394
- tescmd serve 5YJ3... --fields charging # Battery, voltage, current
395
- tescmd serve 5YJ3... --fields all # Everything (120+ fields)
396
-
397
- # Override polling interval
398
- tescmd serve 5YJ3... --interval 5 # Every 5 seconds
399
-
400
- # JSONL output for scripting (non-TTY / piped)
401
- tescmd serve 5YJ3... --no-mcp --format json | jq .
402
-
403
- # Disable CSV log
404
- tescmd serve 5YJ3... --no-log
405
-
406
- # Legacy Rich Live dashboard
407
- tescmd serve 5YJ3... --legacy-dashboard
408
- ```
409
-
410
- **Requires Tailscale** with Funnel enabled. The serve command starts a local WebSocket server, exposes it via Tailscale Funnel (handles TLS + NAT traversal), configures Tesla to push data to it, and renders a full-screen TUI with live telemetry data, server info (MCP URL, tunnel, sinks), unit conversion, and connection status. Press `q` to quit.
411
-
412
- By default, telemetry sessions write a wide-format CSV log to `~/.config/tescmd/logs/` with one row per frame and one column per subscribed field. Disable with `--no-log`.
413
-
414
- `tescmd vehicle telemetry stream` is an alias for `tescmd serve --no-mcp`.
415
-
416
- ### Telemetry vs Polling Costs
417
-
418
- | Approach | 1 vehicle, 5-second interval, 24 hours | Monthly cost estimate |
419
- |---|---|---|
420
- | **Polling `vehicle_data`** | ~17,280 requests × $0.001 = **$17/day** | **$500+/month** |
421
- | **Fleet Telemetry streaming** | 1 config create + 1 config delete = **2 requests** | **< $0.01/month** |
422
-
423
- Fleet Telemetry streaming is a flat-cost alternative: you pay only for the initial config setup and teardown, regardless of how much data flows. The tradeoff is that you need Tailscale running on a machine to receive the push.
424
-
425
- ## Key Enrollment & Vehicle Command Protocol
426
-
427
- Newer Tesla vehicles require commands to be signed using the [Vehicle Command Protocol](https://github.com/teslamotors/vehicle-command). tescmd handles this transparently:
428
-
429
- 1. **Generate a key pair** — `tescmd key generate` creates an EC P-256 key pair
430
- 2. **Enroll on vehicle** — `tescmd key enroll <VIN>` sends the public key to the vehicle; approve in the Tesla app
431
- 3. **Commands are signed automatically** — once enrolled, tescmd uses ECDH sessions + HMAC-SHA256 to sign commands via the `signed_command` endpoint
432
-
433
- ```bash
434
- # Generate EC key pair
435
- tescmd key generate
436
-
437
- # Enroll on a vehicle (interactive approval via Tesla app)
438
- tescmd key enroll 5YJ3E1EA1NF000000
439
-
440
- # Commands are now signed automatically
441
- tescmd security lock --wake
442
- ```
443
-
444
- The `command_protocol` setting controls routing:
445
-
446
- | Value | Behavior |
447
- |---|---|
448
- | `auto` (default) | Use signed path when keys are enrolled; fall back to unsigned |
449
- | `signed` | Require signed commands (error if no keys) |
450
- | `unsigned` | Force legacy REST path (skip signing) |
451
-
452
- Set via `TESLA_COMMAND_PROTOCOL` environment variable or in your config.
453
-
454
- See [docs/vehicle-command-protocol.md](docs/vehicle-command-protocol.md) for the full protocol architecture.
455
-
456
- ## Agent Integration
457
-
458
- tescmd is designed for use by AI agents and automation platforms. Agents like [Claude Code](https://github.com/anthropics/claude-code), Claude Desktop, and other LLM-powered tools can invoke tescmd commands, parse the structured JSON output, and act on your behalf.
459
-
460
- **Why tescmd works well as an agent tool:**
461
-
462
- - **Structured JSON output** — piped/non-TTY mode automatically emits parseable JSON with consistent schema
463
- - **Cost protection** — agents won't accidentally trigger billable wake calls without `--wake`; the default behavior is safe
464
- - **Cache-aware** — every read command is cached; repeated queries from an agent within the TTL window cost nothing
465
- - **Meaningful exit codes** — agents can branch on success/failure without parsing output
466
- - **Stateless invocations** — each command is self-contained; no session state to manage
467
- - **Signed commands** — when keys are enrolled, commands are signed transparently; no agent-side crypto needed
468
-
469
- **Example agent workflow:**
470
-
471
- ```bash
472
- # Agent checks battery (cache hit if recent)
473
- tescmd charge status --format json
474
-
475
- # Agent decides to start charging
476
- tescmd charge start --wake --format json
477
-
478
- # Agent verifies the command took effect (cache was invalidated)
479
- tescmd charge status --format json --fresh
480
- ```
481
-
482
- See [docs/bot-integration.md](docs/bot-integration.md) for the full JSON schema, exit code reference, and headless authentication setup.
483
-
484
- ## Development
485
-
486
- ```bash
487
- # Clone and install in dev mode
488
- git clone https://github.com/oceanswave/tescmd.git
489
- cd tescmd
490
- pip install -e ".[dev]"
491
-
492
- # Run checks
493
- ruff check src/ tests/
494
- ruff format --check src/ tests/
495
- mypy src/
496
- pytest
497
-
498
- # Run a specific test
499
- pytest tests/cli/test_auth.py -v
500
-
501
- # Validate API coverage against Tesla Fleet API spec
502
- python scripts/validate_fleet_api.py
503
- ```
504
-
505
- ### API Coverage Validation
506
-
507
- tescmd ships a spec-driven validation utility that compares our implementation against the Tesla Fleet API. The canonical spec lives at `spec/fleet_api_spec.json` (sourced from Tesla's docs and Go SDK), and `scripts/validate_fleet_api.py` validates all API methods, parameters, and types using AST introspection.
508
-
509
- ```bash
510
- python scripts/validate_fleet_api.py # Summary
511
- python scripts/validate_fleet_api.py --verbose # All endpoints
512
- python scripts/validate_fleet_api.py --json # Machine-readable
513
- ```
514
-
515
- Run this periodically or after modifying API methods to catch drift.
516
-
517
- See [docs/development.md](docs/development.md) for detailed contribution guidelines.
518
-
519
- ## Documentation
520
-
521
- - [Setup Guide](docs/setup.md) — step-by-step walkthrough of `tescmd setup`
522
- - [FAQ](docs/faq.md) — common questions about tescmd, costs, hosting, and configuration
523
- - [Command Reference](docs/commands.md) — detailed usage for every command
524
- - [API Costs](docs/api-costs.md) — detailed cost breakdown and savings calculations
525
- - [Bot Integration](docs/bot-integration.md) — JSON schema, exit codes, telemetry streaming, headless auth
526
- - [OpenClaw Bridge](docs/openclaw.md) — gateway protocol, bidirectional commands, trigger subscriptions, geofencing
527
- - [MCP Server](docs/mcp.md) — tool reference, authentication, custom tools, trigger polling
528
- - [Architecture](docs/architecture.md) — layered design, module responsibilities, design decisions
529
- - [Vehicle Command Protocol](docs/vehicle-command-protocol.md) — ECDH sessions and signed commands
530
- - [Authentication](docs/authentication.md) — OAuth2 PKCE flow, token storage, scopes
531
- - [Development](docs/development.md) — contribution guidelines, testing, linting
532
-
533
- ## Changelog
534
-
535
- See [CHANGELOG.md](CHANGELOG.md) for release history.
536
-
537
- ## License
538
-
539
- MIT
540
-
541
- <p align="center">
542
- <img src="images/tescmd_logo.jpeg" alt="tescmd logo" width="180">
543
- </p>
File without changes