Welcome to Tesla Motors Club
Discuss Tesla's Model S, Model 3, Model X, Model Y, Cybertruck, Roadster and More.
Register

Model S REST API

This site may earn commission on affiliate links.
Here's another newb question. Am I correct in assuming that if I want to check if I remembered to plug my car in at night at, say, 11pm.....That if the car is "asleep" (which mine seems to usually be), I will have to wake it up in order to successfully query it in order to find out that it's plugged in? I think this is true, but I'm being very careful to not wake the car unless absolutely necessary to avoid unwanted vampires.

This is also another of the reasons why I write to a real database instead of just a flat file, I can use code logic to go backwards in time to the last time the car was driven and check if the GPS matches my garage when the car went into park, then check if the car was plugged in. You can do the same on a flat file but it'll be resource heavy and slow to query through all that data.
 
Here's the code. I removed the libraries and made it all functions, changed the switches to static variables at the top you'll need to set with your information. It's very repetitive now but it'll make it easier to understand. The workflow is pretty simple.

Check if there is an encrypted token saved
Generate one, encrypt it and save it locally if there isn't one already
Decrypt the token from file and verify it hasn't expired
Query the state of the vehicle (quit if asleep)
Write results to SQL

Let me know if you get stuck.

EDIT: Forums is doing some weird stuff with the PasteBin link (Remove the spaces from below)
h t t p s : / / pastebin.com/NxJs7i8M

EDIT on the EDIT: I also forgot to mention, I have an S so i'm only saving the metrics I care about to SQL, I know the API returns more than is being written but I simplified the code to where you can easily add more metrics for an X or 3 if you wanted to, oh and change the encryption key after you save it locally since it's posted on the internet (just update the numbers on the encryption and decryption functions).
So I got your code mostly working on my flat csv file. Thanks again for giving me 90% of my project!

One of the problems I am having is probably related to my modified csv output.... One of the parameters (option_codes) contains values that include commas and are showing up as unique columns vs part of Option_codes. Here's my option_code result :

"option_codes":"AD15,MDL3,PBSB,RENA,BT37,ID3W,RF3G,S3PB,DRLH,DV2W,... "

None of the data in my csv file contains quotes and so there's no way to differentiate between new keys and values. I am not sure how to solve this problem yet, but I know that I am not up for learning SQL at this time!
 
So I got your code mostly working on my flat csv file. Thanks again for giving me 90% of my project!

One of the problems I am having is probably related to my modified csv output.... One of the parameters (option_codes) contains values that include commas and are showing up as unique columns vs part of Option_codes. Here's my option_code result :

"option_codes":"AD15,MDL3,PBSB,RENA,BT37,ID3W,RF3G,S3PB,DRLH,DV2W,... "

None of the data in my csv file contains quotes and so there's no way to differentiate between new keys and values. I am not sure how to solve this problem yet, but I know that I am not up for learning SQL at this time!


Np, I had to learn PS and Rest the hard way so I don't mind paying it forward.

As for.l your quote issue you can either modify the property on the object and quote wrap it or replace the commas for something else.

Or you can use convert-csv to get the line as a string and then replace the commas for tabs and make the file a tsv, then pipe it to export-file.

Im on my phone so I can't give you examples let me know if you get stuck.
 
The API seems to be working only intermittently, the last two days. Most of the failures are for "bad gateway". What's weird is that Tesla announced planned maintenance for Monday night, but my script saw no errors then, querying every 5 minutes. But since Wednesday morning, I've had lots of errors.
 
  • Like
Reactions: SeBsZ
@L-P-G , hope you don't mind, but I'm getting the following error often, but NOT always when I pull the Climate State data. Any ideas why?

Code:
VERBOSE: Getting Vehicles
VERBOSE: Getting Vehicle State
VERBOSE: Getting Vehicle Drive State
VERBOSE: Getting Vehicle GUI Settings
VERBOSE: Getting Vehicle Charge State
VERBOSE: Getting Vehicle Climate State
Invoke-RestMethod : {"response":null,"error":"operation_timedout for txid
`98259d826779cd9578d4fc10dcbcd35f`}","error_description":""}
At C:\xxxx\Script rev3.ps1:213 char:21
+     $restResponse = Invoke-RestMethod -Uri "https://owner-api.teslamotors.com/ap ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExc
   eption
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
 
@L-P-G , hope you don't mind, but I'm getting the following error often, but NOT always when I pull the Climate State data. Any ideas why?

Code:
VERBOSE: Getting Vehicles
VERBOSE: Getting Vehicle State
VERBOSE: Getting Vehicle Drive State
VERBOSE: Getting Vehicle GUI Settings
VERBOSE: Getting Vehicle Charge State
VERBOSE: Getting Vehicle Climate State
Invoke-RestMethod : {"response":null,"error":"operation_timedout for txid
`98259d826779cd9578d4fc10dcbcd35f`}","error_description":""}
At C:\xxxx\Script rev3.ps1:213 char:21
+     $restResponse = Invoke-RestMethod -Uri "https://owner-api.teslamotors.com/ap ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExc
   eption
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

That an operation timed out error. Either the api is taking too long to respond or it's not responding for some reason.

You can add a -timeout switch to the invoke-rest method on that line and give it 5 or 10 seconds hard-coded timeout. The api shouldn't take any longer than 10 seconds to respond (unless the car is asleep or there is an issue with the api)

Or you can add a try catch and add your own logic to handle any errors.
 
That an operation timed out error. Either the api is taking too long to respond or it's not responding for some reason.

You can add a -timeout switch to the invoke-rest method on that line and give it 5 or 10 seconds hard-coded timeout. The api shouldn't take any longer than 10 seconds to respond (unless the car is asleep or there is an issue with the api)

Or you can add a try catch and add your own logic to handle any errors.
I can't believe it's asleep, because it is pulling the climate data right at the end of pulling all the other data (vehicle, drive, GUI, and charge). These pulls all happen within seconds of each other. If I add the -timeout switch with 10 second timeout to the climate call, if it doesn't respond in 10 seconds, what happens differently?

On a side note, I've just about completed my version of your script and have it adding my "as measured" EVSE data to my data collection and am seeing charging efficiency. I also have it letting my know at 11pm if my car isn't plugged in. So far so good with everything (except the occasion timeout per above) and really appreciate the help!
 
I can't believe it's asleep, because it is pulling the climate data right at the end of pulling all the other data (vehicle, drive, GUI, and charge). These pulls all happen within seconds of each other. If I add the -timeout switch with 10 second timeout to the climate call, if it doesn't respond in 10 seconds, what happens differently?

On a side note, I've just about completed my version of your script and have it adding my "as measured" EVSE data to my data collection and am seeing charging efficiency. I also have it letting my know at 11pm if my car isn't plugged in. So far so good with everything (except the occasion timeout per above) and really appreciate the help!

The -timeout simply tells the command to wait at least 10 seconds for a response before giving up if it doesn't then you get the same error, hence why a try catch would be a better fix.

You could also add time sleeps between each api endpoint hit as that could also be it, this isn't an issue on my S but I have the older non-face-lift version so I'm a few hardware revisions behind.

Lastly you could switch over the code to use the /data enpoint instead as that will collect all the data in a single hit but you'll have to modify your export objects to match the new returned JSON.
 
The -timeout simply tells the command to wait at least 10 seconds for a response before giving up if it doesn't then you get the same error, hence why a try catch would be a better fix.

You could also add time sleeps between each api endpoint hit as that could also be it, this isn't an issue on my S but I have the older non-face-lift version so I'm a few hardware revisions behind.

Lastly you could switch over the code to use the /data enpoint instead as that will collect all the data in a single hit but you'll have to modify your export objects to match the new returned JSON.
I thought the API required the data to be pulled in separate calls, ie:
https://owner-api.teslamotors.com/api/1/vehicles/vehicle_id/data_request/charge_state = charging info
https://owner-api.teslamotors.com/api/1/vehicles/vehicle_id/data_request/climate_state = climate info

How would you make a single collection?

PS - Sorry if this is simple, my coding is purely a hobby not a profession!
 
I thought the API required the data to be pulled in separate calls, ie:
https://owner-api.teslamotors.com/api/1/vehicles/vehicle_id/data_request/charge_state = charging info
https://owner-api.teslamotors.com/api/1/vehicles/vehicle_id/data_request/climate_state = climate info

How would you make a single collection?

PS - Sorry if this is simple, my coding is purely a hobby not a profession!
Use the relatively new /data endpoint

From memory it is /$carid/data
 
I thought the API required the data to be pulled in separate calls, ie:
https://owner-api.teslamotors.com/api/1/vehicles/vehicle_id/data_request/charge_state = charging info
https://owner-api.teslamotors.com/api/1/vehicles/vehicle_id/data_request/climate_state = climate info

How would you make a single collection?

PS - Sorry if this is simple, my coding is purely a hobby not a profession!

A few months ago a new endpoint "/data" was found on an app update, this endpoint is what I was referring to. It does all the hits at once, I wrote my code before this endpoint was published so that's why it does individual hits.
 
  • Like
Reactions: dpskipper
A few months ago a new endpoint "/data" was found on an app update
Not that it matters much, but actually I think it's been there for around a year. I wrote some scripts last year and I used /data. And looking through this thread, I can see some references to the /data endpoint back to at least Feb 2017.

Anyways, I did the same thing - converted from using several calls to just /data. Just do a pull on that and you'll see what's going on - the charge_state, drive_state, etc. are data structures within the response.