# Teslemetry Teslemetry is a service that provides additional telemetry data for Tesla vehicles. This document provides detailed examples of how to use the Teslemetry class in the Tesla Fleet API library. ## Initialization To use the Teslemetry class, you need to initialize it with an aiohttp ClientSession and an access token. ```python import asyncio import aiohttp from tesla_fleet_api import Teslemetry async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) asyncio.run(main()) ``` ## Troubleshooting: Debug Logging Enable the `tesla_fleet_api` logger at `DEBUG` to log each Teslemetry request's final path segment, `transport=teslemetry`, and result: ```python import logging logging.basicConfig(level=logging.DEBUG) logging.getLogger("tesla_fleet_api").setLevel(logging.DEBUG) ``` Responses that are valid JSON but not objects, such as `null`, lists, or scalars, are returned unchanged and log as `result=success`. ## Ping The `ping` method sends a ping request to the Teslemetry server. ```python async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) response = await teslemetry.ping() print(response) asyncio.run(main()) ``` ## Test API Authentication The `test` method tests the API authentication. ```python async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) response = await teslemetry.test() print(response) asyncio.run(main()) ``` ## Get User Data The `userdata` method retrieves user data. ```python async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) response = await teslemetry.userdata() print(response) asyncio.run(main()) ``` ## Get Metadata The `metadata` method retrieves user metadata, including scopes. ```python async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) response = await teslemetry.metadata() print(response) asyncio.run(main()) ``` ## Get Scopes The `scopes` method retrieves user scopes. ```python async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) response = await teslemetry.scopes() print(response) asyncio.run(main()) ``` ## Server-Side Polling The `server_side_polling` method gets or sets the server-side polling mode for a vehicle. ```python async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) vin = "" # Get the current server-side polling mode response = await teslemetry.server_side_polling(vin) print(response) # Enable server-side polling response = await teslemetry.server_side_polling(vin, value=True) print(response) # Disable server-side polling response = await teslemetry.server_side_polling(vin, value=False) print(response) asyncio.run(main()) ``` ## Force Vehicle Data Refresh The `vehicle_data_refresh` method forces a refresh of the vehicle data. ```python async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) vin = "" response = await teslemetry.vehicle_data_refresh(vin) print(response) asyncio.run(main()) ``` ## Get Streaming Fields The `fields` method retrieves streaming field parameters and metadata. ```python async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) response = await teslemetry.fields() print(response) asyncio.run(main()) ``` ## Get Vehicle Configuration The `vehicle_config` method retrieves the saved vehicle configuration for a specific vehicle. ```python async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) vin = "" response = await teslemetry.vehicle_config(vin) print(response) asyncio.run(main()) ``` ## Get Streaming Configuration The `streaming_config` method retrieves the streaming configuration for a specific vehicle, including certificate, hostname, port, and configurable telemetry fields. ```python async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) vin = "" response = await teslemetry.streaming_config(vin) print(response) asyncio.run(main()) ``` ## Stop Streaming The `stop_streaming` method stops streaming data from a specific vehicle. ```python async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) vin = "" response = await teslemetry.stop_streaming(vin) print(response) asyncio.run(main()) ``` ## Modify Streaming Configuration The `modify_streaming_config` method modifies the streaming configuration for a specific vehicle. ```python async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) vin = "" # Configure specific fields to stream fields = { "BatteryLevel": { "interval_seconds": 60, "minimum_delta": 0.1 }, "VehicleSpeed": { "interval_seconds": 30, "minimum_delta": 0.5 } } response = await teslemetry.modify_streaming_config(vin, fields) print(response) asyncio.run(main()) ``` ## Create Streaming Configuration The `create_streaming_config` method creates or updates the streaming configuration for a specific vehicle. ```python async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) vin = "" # Configure fields to stream fields = { "BatteryLevel": { "interval_seconds": 60 }, "Location": { "interval_seconds": 120 } } response = await teslemetry.create_streaming_config(vin, fields) print(response) asyncio.run(main()) ``` ## Vehicle Custom Commands ### Clear PIN to Drive The `clear_pin_to_drive` method deactivates PIN to Drive on the vehicle. ```python async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) vehicle = teslemetry.vehicles.create("") # Clear PIN to Drive with your 4-digit PIN response = await vehicle.clear_pin_to_drive("1234") print(response) asyncio.run(main()) ``` ### Remove All Impermanent Keys The `remove_key` method removes all impermanent keys from the vehicle. ```python async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) vehicle = teslemetry.vehicles.create("") response = await vehicle.remove_key() print(response) asyncio.run(main()) ``` ### Ping Vehicle The `ping` method performs a no-op on the vehicle. ```python async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) vehicle = teslemetry.vehicles.create("") response = await vehicle.ping() print(response) asyncio.run(main()) ``` ### Data Refresh The `data_refresh` method forces a refresh of the vehicle data. ```python async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) vehicle = teslemetry.vehicles.create("") response = await vehicle.data_refresh() print(response) asyncio.run(main()) ``` ### Closure Control The `closure` method opens, closes, moves, or stops vehicle closures (doors, trunks, charge port, tonneau). ```python async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) from tesla_fleet_api.const import ClosureState vehicle = teslemetry.vehicles.create("") # Open the front trunk response = await vehicle.closure(front_trunk=ClosureState.OPEN) print(response) # Close all doors response = await vehicle.closure( front_driver_door=ClosureState.CLOSE, front_passenger_door=ClosureState.CLOSE, rear_driver_door=ClosureState.CLOSE, rear_passenger_door=ClosureState.CLOSE, ) print(response) asyncio.run(main()) ``` ### Seat Heater The `seat_heater` method sets multiple seat heaters at once. ```python async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) from tesla_fleet_api.const import SeatHeaterLevel vehicle = teslemetry.vehicles.create("") response = await vehicle.seat_heater( front_left=SeatHeaterLevel.HIGH, front_right=SeatHeaterLevel.HIGH, ) print(response) asyncio.run(main()) ``` ### Charge on Solar The `charge_on_solar` method enables or disables charging on solar and sets charge limits. ```python async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) vehicle = teslemetry.vehicles.create("") response = await vehicle.charge_on_solar( enabled=True, lower_charge_limit=20, upper_charge_limit=80, ) print(response) asyncio.run(main()) ``` ### Dashcam Save The `dashcam_save` method saves the last 10 minutes of dashcam footage. ```python async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) vehicle = teslemetry.vehicles.create("") response = await vehicle.dashcam_save() print(response) asyncio.run(main()) ``` ### Play Video The `play_video` method plays a supported video URL in the vehicle. ```python async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) vehicle = teslemetry.vehicles.create("") response = await vehicle.play_video(url="https://www.youtube.com/watch?v=example") print(response) asyncio.run(main()) ``` ### Light Show The `start_light_show` and `stop_light_show` methods control vehicle light shows. ```python async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) vehicle = teslemetry.vehicles.create("") response = await vehicle.start_light_show(show_index=0) print(response) response = await vehicle.stop_light_show() print(response) asyncio.run(main()) ``` ## Energy Site Authorized Clients Teslemetry energy sites support the same raw `list_authorized_clients` command as Fleet API energy sites, plus a typed `find_authorized_clients` helper for consumers that need to inspect the client list. The helper returns an `AuthorizedClients` result. Tesla has not published a schema for this pairing endpoint, so the typed helper only unwraps the confirmed envelope shape - the client list may arrive under either the `authorized_clients` key or the `clients` key (the latter observed live from Tesla Release 953) - and models the confirmed `public_key`, `state`, `roles`, and `verification` fields; `clients` is always a list. `state`, each role, and verification are typed as `AuthorizedClientState`, `AuthorizationRole`, and `AuthorizedVerificationType`, while unknown values are preserved. Only an explicitly empty list under either accepted key parses to `clients == []`; a null response body or an unrecognized response shape raises `tesla_fleet_api.exceptions.InvalidResponse` instead, so malformed data is never mistaken for "no authorized clients". The raw response is still available on `raw` for anything not modeled. The parsing itself lives in the module-level `tesla_fleet_api.teslemetry.energysite.parse_authorized_clients` function, which other callers (e.g. a local/LAN client using the same envelope shape) can reuse directly to get the same `AuthorizedClients` result. For the unparsed response, use `list_authorized_clients()`. `remove_authorized_client(public_key)` accepts raw DER bytes or an already base64-encoded key string. Removal requires no physical presence proof, so any paired key can revoke every other key, including the owner's. These cloud helpers report the gateway's registered-client state as returned by the Teslemetry API. `wait_until_paired()` provides the bounded polling flow and can optionally confirm the cloud state with a signed LAN read; see [Energy: Local Control](energy_local_control.md). ```python async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) energy_site = teslemetry.energySites.create(12345) result = await energy_site.find_authorized_clients() for client in result.clients: print(client.public_key, client.state, client.roles, client.verification) # The untyped response is still available when callers need the exact # Teslemetry payload. raw = await energy_site.list_authorized_clients() print(raw) asyncio.run(main()) ``` ## Energy Site Gateway Address Teslemetry energy sites expose the raw `get_networking_status` command, plus a typed `find_gateway_address` helper that discovers the gateway's LAN IPv4 address - for example to pre-fill the host for the signed local control path shown in [Energy: Local Control](energy_local_control.md). The `ipv4_config` fields in a `networking_status` response have been observed as either raw big-endian uint32 integers or dotted-quad strings; the helper decodes either form and selects an interface for you. Only the `eth` and `wifi` interfaces are considered (never `gsm` - cellular is not a LAN path): the helper prefers whichever has `active_route` set and a decodable address, then falls back to the first of the two (in `eth`, `wifi` order) with any decodable address. A null response body or an unrecognized response shape raises `tesla_fleet_api.exceptions.InvalidResponse`, so malformed data is never mistaken for "no address"; a well-formed response where no interface yields a usable address returns `None` instead. ```python async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) energy_site = teslemetry.energySites.create(12345) address = await energy_site.find_gateway_address() print(address) # e.g. "192.168.1.138", or None # The untyped response is still available when callers need the exact # Teslemetry payload. raw = await energy_site.get_networking_status() print(raw) asyncio.run(main()) ``` ## Energy Site Device Commands Teslemetry energy sites send the gRPC device commands that have no Teslemetry custom route (for example `get_system_info()`, `get_signed_commands_public_key()` and `schedule_backup_event()`) through Teslemetry's generic route `POST /api/1/energy_sites/{id}/command` with the body `{"category", "command_name", "params", "identifier_type"}`. Teslemetry returns the gateway reply unwrapped, as `{"response": {...}}`. See [Fleet API for Energy Sites](fleet_api_energy_sites.md#available-commands). ## Energy Site Battery Dispatch Teslemetry energy sites send `dispatch_battery_power(power_watts, duration_seconds)` and `resume_battery_operation()` through the Teslemetry custom routes `POST /api/1/energy_sites/{id}/command/dispatch_battery_power` and `POST /api/1/energy_sites/{id}/command/resume_battery_operation`. `power_watts` is battery power in watts: positive discharges, negative charges. `duration_seconds` is an integer from 1 to 86400. The library raises `ValueError` before any request on other values. See [Fleet API for Energy Sites](fleet_api_energy_sites.md#available-commands). ```python energy_site = teslemetry.energySites.create(12345) await energy_site.dispatch_battery_power(power_watts=5000, duration_seconds=60) await energy_site.resume_battery_operation() ``` ## Migrate to OAuth The `migrate_to_oauth` method migrates from an access token to OAuth. ```python async def main(): async with aiohttp.ClientSession() as session: teslemetry = Teslemetry( session=session, access_token="", ) response = await teslemetry.migrate_to_oauth(client_id="homeassistant") print(response) asyncio.run(main()) ``` ## OAuth Dynamic Client Registration Teslemetry supports OAuth 2.0 Dynamic Client Registration ([RFC 7591](https://www.rfc-editor.org/rfc/rfc7591)) so each installation can register its own `client_id` instead of every client sharing one hardcoded value. `register_client` is a standalone helper - it needs only an `aiohttp.ClientSession`, not a `Teslemetry` instance, since no `client_id` or access token exists yet at registration time. It always registers a new client; callers are responsible for persisting the returned `client_id` and skipping registration on subsequent runs. It raises `tesla_fleet_api.exceptions.TeslemetryRegistrationError` if the registration endpoint can't be reached, the response isn't valid JSON, or the response doesn't contain a usable `client_id`. ```python import aiohttp from tesla_fleet_api import register_client from tesla_fleet_api.exceptions import TeslemetryRegistrationError async def main(): async with aiohttp.ClientSession() as session: try: registration = await register_client( session, client_name="Home Assistant", software_id="home-assistant", software_version="2026.1.0", ) except TeslemetryRegistrationError as e: print(e) return print(registration.client_id) asyncio.run(main()) ```