From 6022dc3a51b6707f63a64ef1171443040db1ae47 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 8 Jan 2026 08:47:06 +0000 Subject: [PATCH 1/3] Add missing Teslemetry API endpoints Added three Teslemetry-specific API endpoints from the OpenAPI schema: - fields(): GET /fields.json - retrieves streaming field parameters and metadata - vehicle_config(vin): GET /api/vehicle_config/{vin} - gets saved vehicle configuration - streaming_config(vin): GET /api/config/{vin} - gets streaming configuration including certificate, hostname, port, and telemetry fields Also updated the documentation with examples for using these new endpoints. --- docs/teslemetry.md | 58 ++++++++++++++++++++++++ tesla_fleet_api/teslemetry/teslemetry.py | 31 +++++++++++++ 2 files changed, 89 insertions(+) diff --git a/docs/teslemetry.md b/docs/teslemetry.md index fb8edef..5df219b 100644 --- a/docs/teslemetry.md +++ b/docs/teslemetry.md @@ -159,3 +159,61 @@ async def main(): 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()) +``` diff --git a/tesla_fleet_api/teslemetry/teslemetry.py b/tesla_fleet_api/teslemetry/teslemetry.py index 128541b..33a2f0d 100644 --- a/tesla_fleet_api/teslemetry/teslemetry.py +++ b/tesla_fleet_api/teslemetry/teslemetry.py @@ -122,3 +122,34 @@ async def migrate_to_oauth( new_token["expires_in"] = int(new_token["expires_in"]) new_token["expires_at"] = time() + new_token["expires_in"] return new_token + + async def fields(self) -> dict[str, Any]: + """Get streaming field parameters and metadata.""" + return await self._request( + Method.GET, + "fields.json", + ) + + async def vehicle_config(self, vin: str) -> dict[str, Any]: + """Get the saved vehicle configuration. + + Args: + vin: Vehicle identification number + """ + return await self._request( + Method.GET, + f"api/vehicle_config/{vin}", + ) + + async def streaming_config(self, vin: str) -> dict[str, Any]: + """Get the streaming configuration for a specific vehicle. + + Returns certificate, hostname, port, and configurable telemetry fields. + + Args: + vin: Vehicle identification number + """ + return await self._request( + Method.GET, + f"api/config/{vin}", + ) From ee5eae9edd41f80641b372a62c638d35f8bf1680 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 8 Jan 2026 08:55:22 +0000 Subject: [PATCH 2/3] Add remaining Teslemetry API endpoints from OpenAPI schema Added missing Teslemetry-specific endpoints: Main Teslemetry class (teslemetry.py): - vehicle_image(vin): GET /api/image/{vin} - redirect to Tesla Design Studio vehicle image - stop_streaming(vin): DELETE /api/config/{vin} - stop streaming data from vehicle - modify_streaming_config(vin, fields): PATCH /api/config/{vin} - modify streaming configuration - create_streaming_config(vin, fields): POST /api/config/{vin} - create/update streaming configuration TeslemetryVehicle custom commands (vehicles.py): - clear_pin_to_drive(pin): POST /api/1/vehicles/{vin}/custom_command/clear_pin_to_drive - deactivate PIN to Drive - remove_key(): POST /api/1/vehicles/{vin}/custom_command/remove_key - remove all impermanent keys Updated documentation with examples for all new endpoints. All endpoints verified against https://api.teslemetry.com/openapi.yaml --- docs/teslemetry.md | 145 +++++++++++++++++++++++ tesla_fleet_api/teslemetry/teslemetry.py | 52 ++++++++ tesla_fleet_api/teslemetry/vehicles.py | 19 +++ 3 files changed, 216 insertions(+) diff --git a/docs/teslemetry.md b/docs/teslemetry.md index 5df219b..98cbc35 100644 --- a/docs/teslemetry.md +++ b/docs/teslemetry.md @@ -217,3 +217,148 @@ async def main(): 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()) +``` + +## Get Vehicle Image + +The `vehicle_image` method gets the redirect URL to the Tesla Design Studio image of the vehicle. + +```python +async def main(): + async with aiohttp.ClientSession() as session: + teslemetry = Teslemetry( + session=session, + access_token="", + ) + + vin = "" + + response = await teslemetry.vehicle_image(vin) + 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()) +``` diff --git a/tesla_fleet_api/teslemetry/teslemetry.py b/tesla_fleet_api/teslemetry/teslemetry.py index 33a2f0d..b08305a 100644 --- a/tesla_fleet_api/teslemetry/teslemetry.py +++ b/tesla_fleet_api/teslemetry/teslemetry.py @@ -153,3 +153,55 @@ async def streaming_config(self, vin: str) -> dict[str, Any]: Method.GET, f"api/config/{vin}", ) + + async def stop_streaming(self, vin: str) -> dict[str, Any]: + """Stop streaming data from a specific vehicle. + + Args: + vin: Vehicle identification number + """ + return await self._request( + Method.DELETE, + f"api/config/{vin}", + ) + + async def modify_streaming_config( + self, vin: str, fields: dict[str, Any] + ) -> dict[str, Any]: + """Modify the streaming configuration for a specific vehicle. + + Args: + vin: Vehicle identification number + fields: Fields to stream with their configuration + """ + return await self._request( + Method.PATCH, + f"api/config/{vin}", + json={"fields": fields}, + ) + + async def create_streaming_config( + self, vin: str, fields: dict[str, Any] + ) -> dict[str, Any]: + """Create/update the streaming configuration for a specific vehicle. + + Args: + vin: Vehicle identification number + fields: Fields to stream with their configuration + """ + return await self._request( + Method.POST, + f"api/config/{vin}", + json={"fields": fields}, + ) + + async def vehicle_image(self, vin: str) -> dict[str, Any]: + """Get redirect URL to Tesla Design Studio image of the vehicle. + + Args: + vin: Vehicle identification number + """ + return await self._request( + Method.GET, + f"api/image/{vin}", + ) diff --git a/tesla_fleet_api/teslemetry/vehicles.py b/tesla_fleet_api/teslemetry/vehicles.py index 61860d2..e00da22 100644 --- a/tesla_fleet_api/teslemetry/vehicles.py +++ b/tesla_fleet_api/teslemetry/vehicles.py @@ -260,6 +260,25 @@ async def start_light_show( json=data, ) + async def clear_pin_to_drive(self, pin: str) -> dict[str, Any]: + """Deactivates PIN to Drive. + + Args: + pin: 4-digit PIN to clear + """ + return await self._request( + Method.POST, + f"api/1/vehicles/{self.vin}/custom_command/clear_pin_to_drive", + json={"pin": pin}, + ) + + async def remove_key(self) -> dict[str, Any]: + """Remove all impermanent keys from the vehicle.""" + return await self._request( + Method.POST, + f"api/1/vehicles/{self.vin}/custom_command/remove_key", + ) + class TeslemetryVehicles(Vehicles): """Class containing and creating vehicles.""" From f5d6029589927ba20f3c2af3be3ce9d719aafc71 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 8 Jan 2026 09:22:29 +0000 Subject: [PATCH 3/3] Remove vehicle_image endpoint - returns PNG redirect not suitable for Python --- docs/teslemetry.md | 20 -------------------- tesla_fleet_api/teslemetry/teslemetry.py | 11 ----------- 2 files changed, 31 deletions(-) diff --git a/docs/teslemetry.md b/docs/teslemetry.md index 98cbc35..e676511 100644 --- a/docs/teslemetry.md +++ b/docs/teslemetry.md @@ -300,26 +300,6 @@ async def main(): asyncio.run(main()) ``` -## Get Vehicle Image - -The `vehicle_image` method gets the redirect URL to the Tesla Design Studio image of the vehicle. - -```python -async def main(): - async with aiohttp.ClientSession() as session: - teslemetry = Teslemetry( - session=session, - access_token="", - ) - - vin = "" - - response = await teslemetry.vehicle_image(vin) - print(response) - -asyncio.run(main()) -``` - ## Vehicle Custom Commands ### Clear PIN to Drive diff --git a/tesla_fleet_api/teslemetry/teslemetry.py b/tesla_fleet_api/teslemetry/teslemetry.py index b08305a..ddc087e 100644 --- a/tesla_fleet_api/teslemetry/teslemetry.py +++ b/tesla_fleet_api/teslemetry/teslemetry.py @@ -194,14 +194,3 @@ async def create_streaming_config( f"api/config/{vin}", json={"fields": fields}, ) - - async def vehicle_image(self, vin: str) -> dict[str, Any]: - """Get redirect URL to Tesla Design Studio image of the vehicle. - - Args: - vin: Vehicle identification number - """ - return await self._request( - Method.GET, - f"api/image/{vin}", - )