timdorr / tesla-api Goto Github PK
View Code? Open in Web Editor NEW🚘 A Ruby gem and unofficial documentation of Tesla's JSON API for the Model S, 3, X, and Y.
Home Page: https://tesla-api.timdorr.com/
License: MIT License
🚘 A Ruby gem and unofficial documentation of Tesla's JSON API for the Model S, 3, X, and Y.
Home Page: https://tesla-api.timdorr.com/
License: MIT License
Thanks to a number of contributors who are much wiser than I, I've got a plain vanilla version of what I'm trying to do in Java working in EclipseJavaNeon. But ultimately, I'm trying to get this into an Android app. The goal is ultimately to close an open (or vented) sunroof. There is something about how I'm using the API that's just not right (or I'm just too uneducated to be programming this stuff). There are two parts to my problem right now and a kind of third problem listed way below.
1) On the effort to get the access token, I can get the token but only if all the parameters are in the URL itself with https://private-anon-3f2af7cab3-timdorr.apiary-proxy.com/oauth/token?client_id=e4a9949fcfa04068f59abb5a658f2bac0a3428e4652315490b659d5ab3f35a9e&client_secret=c75f14bbadc8bee3a7594412c31416f8300256d7668ea7e6e7f06727bfb9d220&[email protected]&password=[my password]&grant_type=password
This works but it seems as if I should be able to pass the parts either as JSON or the equivalent of headers so that it's not passed in plain text with the password. Here's the code that I'm using. This is in a separate thread as required by Android and I THINK I'm managing the Async stuff correctly. So the following works but I'd like to get the parameters out of the URL if there's a way to do it:
String realUrl = "https://owner-api.teslamotors.com/oauth/token?grant_type=password&client_id={id token}&client_secret={client secret token}&email={[email protected]}&password={mypassword}";
URL url = null;
try {
url = new URL(realUrl);
} catch (MalformedURLException e) {
e.printStackTrace();
}
HttpsURLConnection myURLConnection = null;
try {
myURLConnection = (HttpsURLConnection) url.openConnection();
} catch (IOException e) {
e.printStackTrace();
}
try {
myURLConnection.setRequestMethod("POST");
} catch (ProtocolException e) {
e.printStackTrace();
}
myURLConnection.setConnectTimeout(3000); **//THIS LINE DOESN’T SEEM TO MAKE ANY DIFFERENCE WHEN I LOOK AT DEBUG**
myURLConnection.setReadTimeout(3000); **//DITTO WITH THIS LINE**
myURLConnection.setRequestProperty("User-Agent", "Mozilla/5.0");
myURLConnection.setRequestProperty("Content-Type", "application/json");
myURLConnection.setDoOutput(true);
myURLConnection.setDoInput(true);
_/*Tried to put all of the parameters into JSON and write it here, but this didn’t work
String json = "{\"grant_type\":"\password,client_id\":\"[id token]\","\client_secret\":"\[client secret token]\",\"email\":\"[email protected]\",\"password\":\"mypassword\"}";
DataOutputStream dStream = null;
try {
dStream = new DataOutputStream(myURLConnection.getOutputStream());
dStream.writeBytes(json);
dStream.flush();
dStream.close();
} catch (IOException e) {
e.printStackTrace();
} */_
int response = 0;
try {
response = myURLConnection.getResponseCode();
} catch (IOException e) {
e.printStackTrace();
}
StringBuffer result = new StringBuffer();
BufferedReader rd;
try {
rd = new BufferedReader(new InputStreamReader(myURLConnection.getInputStream()));
String line = "";
while ((line = rd.readLine()) != null) {
result.append(line);
}
rd.close();
} catch (IOException e) {
e.printStackTrace();
}
myURLConnection.disconnect();
accessToken = [subroutine pulls global String accessToken from result; works];
return;
2) Once I have a good access token, I'm next trying to get the vehicleID. The following code is returning a 404 from the server. I suspect I'm missing something really easy and obvious. Any help here again would be greatly appreciated:
String realUrl = "https://owner-api.teslamotors.com/api/1/vehicles";
URL url = null;
try {
url = new URL(realUrl);
} catch (MalformedURLException e) {
e.printStackTrace();
}
HttpsURLConnection myURLConnection = null;
try {
myURLConnection = (HttpsURLConnection) url.openConnection();
} catch (IOException e) {
e.printStackTrace();
}
try {
myURLConnection.setRequestMethod("GET");
} catch (ProtocolException e) {
e.printStackTrace();
}
myURLConnection.setConnectTimeout(3000); **//THIS LINE DOESN’T SEEM TO MAKE ANY DIFFERENCE WHEN I LOOK AT DEBUG**
myURLConnection.setReadTimeout(3000); **//DITTO WITH THIS LINE**
myURLConnection.setRequestProperty("User-Agent", "Mozilla/5.0");
myURLConnection.setDoOutput(true);
myURLConnection.setDoInput(true);
myURLConnection.setRequestProperty("Authorization", "Bearer " + accessToken); //accessToken is global variable set in getAuth()
int response = 0;
try {
response = myURLConnection.getResponseCode();
**//response = 404!!!!**
} catch (IOException e) {
e.printStackTrace();
}
StringBuffer result = new StringBuffer();
BufferedReader rd;
try {
rd = new BufferedReader(new InputStreamReader(myURLConnection.getInputStream()));
String line = "";
while ((line = rd.readLine()) != null) {
result.append(line);
}
rd.close();
} catch (IOException e) {
e.printStackTrace();
}
myURLConnection.disconnect();
vehicleID = [subroutine pulls global String vehicleID from result; probably works but haven’t gotten useful result yet];
return;
3. If anyone has any thoughts about why the .setConnectTimeout and .setReadTimeout methods don't seem to be changing the values for the properties when I'm looking the debugger either for myURLConnection or for the delegate property of myURLConnection, again, I would appreciate your ideas. As a related item, I learned that the .setRequestMethod, .setDoOutput, and .setDoInput methods don't change these properties for myURLConnection but do set these properties for the delegate, but this doesn't happen for the . ...Timeout methods. Why?
THANK YOU!
Not sure if this is appropriate place to post this issue - apologies if not..
I am using:
http://docs.timdorr.apiary.io/#reference/vehicle-commands/open-trunkfrunk/get-an-access-token?console=1
Passing in the grant_type, client_id, client_secret and my valid Tesla email and password (in plain text -- is that the issue?) --- and when I run that on 'Production' and choose 'Call Resource' - I always get a 404 error....
I can't figure out what I'm doing wrong, but suspect that this call should work. NOOb :|
I am not able to get the response from Vehicle State APIs, i am getting this error -
{ "response": null, "error": "not_found", "error_description": "" }
However Token and Vehicle details APIs are working fine. I am using this API
In the apiary documentation, almost all the methods require a "vehicle_id" parameter, however it actually seems this must be the value labeled "id" in the list of all vehicles.
You can now "Summon" via the app and there is also some HomeLink capability. I have a 2012 Model S, so I'm unable to live test this stuff, but hopefully I can use the HomeLink APIs nonetheless.
The streaming API works as intended, and returns updates every ~250 msec.
The streaming API connects successfully, but does not return anything regardless of the state of the Model 3 (awake, driving, etc - nothing is returned).
This started as soon as my Model 3 updated to version 2018.18.3 04dfd3c. Streaming was working before that, then immediately after the update, it began returning nothing. I've restarted the car, restarted the server, tried across several different days, and the streaming API continues to return nothing.
Hi,
I saw that there's a new all data API that is not yet documented. If i have time i can do PR for this.
Endpoint: /api/1/vehicles/vehicle_ID/data
Hi Tim,
Sorry if this is not the place for this type of question. Do you have a place where we can chat / maillist etc? Also I have a model 3 and pretty much everything you have done with the s api works for me. Minus the sunroom since it does not have one :)
Websocket stuff.
I didnt see any documentation but do you know anything about getting notifications. Say when you unplug your charger and in the app you get messages saying its unplugged? Is this communication documented?
API Sniffing.
I used to use a packet capture app to sniff ssl enabled communications but its no longer working (I suspect cert pinning?) How are you inspecting the apis from the app? Or are you decompiling it?
Thanks for the help and if you need any model 3 specific tests let me know.
Riley
all commands but wakeup have /command/ after vehicle_id
https://owner-api.teslamotors.com/api/1/vehicles/vehicle_id/wake_up
ex:
https://owner-api.teslamotors.com/api/1/vehicles/vehicle_id/command/reset_valet_pin
Hi there,
can someone explain me how to get the expire_in parameter after receiving the token?
tesla_api = TeslaApi::Client.new(email, client_id, client_secret)
tesla_api.login!(password)
Thanks
In charge state there is an example with non valid json:
{
"response": {
"charging_state": "Complete", // "Charging", ??
"charge_to_max_range": false, // current std/max-range setting
"max_range_charge_counter": 0,
"fast_charger_present": false, // connected to Supercharger?
"battery_range": 239.02, // rated miles
"est_battery_range": 155.79, // range estimated from recent driving
"ideal_battery_range": 275.09, // ideal miles
"battery_level": 91, // integer charge percentage
"battery_current": -0.6, // current flowing into battery
"charge_starting_range": null,
"charge_starting_soc": null,
"charger_voltage": 0, // only has value while charging
"charger_pilot_current": 40, // max current allowed by charger & adapter
"charger_actual_current": 0, // current actually being drawn
"charger_power": 0, // kW (rounded down) of charger
"time_to_full_charge": null, // valid only while charging
"charge_rate": -1.0, // float mi/hr charging or -1 if not charging
"charge_port_door_open": true
}
}
Should I fork and fix it?
I'd like to be able to scale down the current drawn while charging if my solar panels are generating much power. I could easily just switch the charging off, but I'd like to be able to make the most out of what is being produced. Do you know of such an API or where else I could ask?
For my TMX (2018.26 3bbd9fd), the OPEN_TRUNK documentation seemed to be off. After fiddling, I found that the suggested URL parameter "which_trunk" should actually be in the posted JSON body.
POST https://owner-api.teslamotors.com/api/1/vehicles/XXXXXXX/command/trunk_open
with JSON body:
{
"which_trunk": "rear"
}
In the URL, XXXXXXX is your vehicle ID, of course.
Am I doing something obvious wrong? Using a basic REST post I'm getting a 404
Tesla has moved quite a bit around on the API with the release of 6.0 and the latest apps. There are a couple new endpoints and most have been moved around.
The server has switched to owner-api.teslamotors.com
and there is certificate pinning in the apps, making sniffing via proxy more difficult. I may try poking around with APK Studio to see if I can remove the pin or have it trust a different cert.
owner-api.teslamotors.com
/command/
endpoints
charge_max_range
charge_standard
sun_roof_control
flash_lights
honk_horn
door_lock
charge_port_door_open
trunk_open
remote_start_drive
upcoming_calendar_entries
set_temps
charge_start
auto_conditioning_start
charge_stop
auto_conditioning_stop
door_unlock
/data_request/
endpoints
charge_state
climate_state
drive_state
gui_settings
vehicle_state
wake_up
mobile_enabled
notification_preferences
vehicle_subscriptions
Hi Tim,
is there a sandbox mode? Who would I need to contact, so I get a demo dataset? I am trying to prepare sth for an upcoming hackathon, but buying a Tesla for that is a bit out of budget. ;)
Cheers, Oliver
Have you updated the API URL endpoints since the changed from teslamotors to just tesla...I suspect API changed...
Let me start by saying that this is meant to be progressive, and I have come across each of these through the feeling of "why did I need to go through trial-and-error to reach that answer", and thought that there might need to be an update.
Anyways, onto the list, feel free to add as I don't have a ton to push on initially, although I know there are some hiding out there.
Recently i was trying to implement the streaming API on my swift lib but i noticed that Tesla is not using websockets anymore.
Request
GET /stream/VEHICLE_ID/?values=speed,odometer,soc,elevation,est_heading,est_lat,est_lng,power,shift_state,range,est_range,heading HTTP/1.1
Connection: Upgrade
Host: streaming.vn.teslamotors.com
Origin: wss://streaming.vn.teslamotors.com/stream/VEHICLE_ID/?values=speed,odometer,soc,elevation,est_heading,est_lat,est_lng,power,shift_state,range,est_range,heading
User-Agent: SwiftWebSocket
Upgrade: websocket
Sec-WebSocket-Version: 13
Authorization: Basic !REMOVED!
Sec-WebSocket-Key: 6Dc+wQBQoGacYAPXzGctvg==
Response
HTTP/1.1 200 OK
Server: nginx
Date: Sun, 23 Apr 2017 13:19:38 GMT
Content-Type: text/event-stream
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: no-cache
This seems to be HTTP SSE traffic. https://en.wikipedia.org/wiki/Server-sent_events
I implemented this into the lib but no data came from the stream.
Streaming URL:
https://streaming.vn.teslamotors.com/stream/VEHICLE_ID/?values=speed,odometer,soc,elevation,est_heading,est_lat,est_lng,power,shift_state,range,est_range,heading
Can anyone here validate that this is in fact HTTP SSE and if so that your car produces events?
http://docs.timdorr.apiary.io/#reference/vehicle-commands/set-valet-mode/set-valet-mode
The valet mode API makes references to 3 parameters but the URI only shows 1.
Can you update it? I don't have a car to test :)
Preemptively creating this issue to add battery pre-heating command docs and methods. Looks like it should be coming in an app update.
https://electrek.co/2017/12/19/tesla-battery-pre-heating-feature-maximize-efficiency-cold-climates/
Hi, i dont know if you notice but the API has been updated recently with lots of changes.
I updated my swift library already here's some changes i found out:
jonasman/TeslaSwift@7ee7a0f
jonasman/TeslaSwift@b3f2641
jonasman/TeslaSwift@09fcbdf
jonasman/TeslaSwift@bc95dab
I am trying to utilize the Tesla Models S JSON API and can’t seem to be able to deserialize the response that gets returned. I am using c# and get the response back for List Vehicles but nothing seems to parse correctly. I have tried a few approaches. Any help or an example would be fantastic. Thank you,
As an array
Vehicles[] Cars = JsonConvert.DeserializeObject<Vehicles[]>(responseData);
foreach (Vehicles car in Cars)
{
int id = car.id;
string name = car.display_name.ToString();
}
As a list
List list = JsonConvert.DeserializeObject<List>(responseData);
public class Vehicles
{
public object color { get; set; }
public object display_name { get; set; }
public int id { get; set; }
public string option_codes { get; set; }
public int user_id { get; set; }
public int vehicle_id { get; set; }
public string vin { get; set; }
public string[] tokens { get; set; }
public string state { get; set; }
}
Apiary is a great tool for documenting REST APIs. However, the Tesla API is not true REST and this incongruity results in a lot of confusion. There are two main issues:
So, I'd like to move the docs off of Apiary and over to Github Pages. We can use the built-in Jekyll or another static site generator. There are quite a few options here. I'm going to get started on the infrastructure ASAP and hopefully we can have this all moved over quickly and easily.
(Doing this partly after the fact)
The library needs to be updated for all the new API changes. This represents a good chance to convert it to a real Ruby gem and publish it.
Client
Vehicle
just creating the issue if anyone finds out the API
Hello,
Would it be possible to add support for changing the charge rate? I'd like to use my surplus power from solar to send it to the grid. Via the Tesla Powerwall API I can see how much power is going to the grid. I'd like to vary the charge rate of the car to match the excess power going to the grid.
I would need someone to sniff the API call from the phone application to capture the POST message and document.
Thank you,
-Vince
Anyone knows what does a wake_up
command do? saw it here:
https://github.com/gglockner/teslajson/blob/master/teslajson.py#L142
I believe there are a few new commands available: http://www.teslamotors.com/blog/software-v60
Did anyone found how to close the liftgate?
I need some help documenting the latest API methods found, including any hidden ones. For instance, set_charge_limit
was added due to variable charge limiting introduced in the 4.5 firmware. There are possibly others.
I'll leave this issue open so others can comment and indicate any endpoints they've found.
Yesterday, using Swift to make a mac application with the API, everything was fine and i could login normally, but today, i keep getting this response from the server, even though my username and password are correct.
Status = "401 Unauthorized"; "Www-Authenticate" = "Bearer realm=\"Doorkeeper\", error=\"\", error_description=\"translation missing: en.doorkeeper.errors.messages\"";
I've checked for errors in the code, but it's fine as far as i can tell..
<NSHTTPURLResponse: 0x618000026a80> { URL: https://owner-api.teslamotors.com/oauth/token?grant_type=password&client_id=e4a9949fcfa04068f59abb5a658f2bac0a3428e4652315490b659d5ab3f35a9e&client_secret=c75f14bbadc8bee3a7594412c31416f8300256d7668ea7e6e7f06727bfb9d220&username=********@*****.***&password=**************** }
I also cannot access the access_token with the Apiary page, so my thoughts are that the client id and secret have been updated.
Thanks!
The URL "https://owner-api.teslamotors.com/oauth/token" for getting an access_token is returning 404, I double checked the URL parameters. Nothing so far.
using "curl --request POST" the response is
{"response":"undefined_method_`strip'_for_nil:nilclass"}
Did anyone found out how to control the trunks?
The ID/Secret used to talk to the Tesla servers seems to have expired. Can you generate a new one (or post how to generate a new one)?
I am able to get an access token and my vehicle id, but all other calls result in 404 errors. I have used both the "vehicle_id" and "id" codes, to no avail. I have a 2016 Model X with the latest firmware build. Is there something specific to a Model X that prevents compatibility with this API? I would appreciate any assistance anyone can offer!
Here is an example of an error I received when trying to retrieve the car's charge state:
Response
404
Headers
• connection:keep-alive
• server:nginx
• date:Thu, 15 Jun 2017 16:58:43 GMT
• content-type:application/json; charset=utf-8
• content-length:60
• status:404 Not Found
• x-frame-options:SAMEORIGIN
• x-xss-protection:1; mode=block
• x-content-type-options:nosniff
• cache-control:no-cache
• x-request-id:c5561f18-e1cc-470d-99ab-4ddfa4598ad3
• x-runtime:0.009613
• x-newrelic-app-data:PxQDVFVRCQITVlZRDgcFV0YdFGQHBDcQUQxLA1tMXV1dSnwZQRNWERdcRE42LGtnH0tLQBsBGVZUAxoDTFNXVgZRDFMKAQQCA1UJUQBNEVRUFBtDAlYIVVMBWFQFBwRSAgkUHwQHDxFVPw==
• via:1.1 vegur
Body
{
"response": null,
"error": "not_found",
"error_description": ""
}
There is a property in the json created_at
that is missing from the examples
A much older version of the official Tesla app allowed you to turn the window defrosters on and off. That API call must still exist, can we figure it out?
I was wondering if there is a way to get the car's battery size? I saw that there is a battery_range
parameter in the response of the charge_state
request (which I assume is the range for the fully charged battery) but it seems like a strange place to put the battery size, which is a static value that should be returned with the car information. Is this parameter referring to something else maybe?
Thanks in advance for the response and for the great work documenting these APIs!!
Some time around the release of the 6.0 firmware, Tesla switched to a more sane oAuth-based API (good move! 👍).
I assume posting the raw oAuth tokens is a no-no, so either instructions need to be provided on how to get them or we leave that as an exercise for the reader. Either way, the project is busted without it.
I am trying to use the set_temps method, but it seems like it can only activate max cool and is ignoring the parameters.
Can anyone confirm or disprove this?
Requesting get to https://owner-api.teslamotors.com/api/1/vehicles/"vehicleID"/data_request/climate_state with correct access header sometimes returns HTML instead of JSON, which seems like without explanation.
Also, some requests to charge also give me a 'Unable to connect to...' error. Maybe these errors should be documented?
Model 3 support just landed in the apps. I haven't done any poking around, but perhaps some new stuff was added? If someone else wants to beat me to it, go right ahead!
Hi there,
I was wondering if there is a code to get the mileage of my tesla?
I am trying to control my trips with the JSON API.
After lots of playing around, I've been able to use almost all of the documented API calls EXCEPT the sun_roof_control.
Whether I'm using the interface provided by Tim Dorr or a simple (ish) Java application I've written, I can't seem to find any combination of sunroof calls parameters that work. States of "close", "open", "comfort", "move" all return 400 errors ({"response": null, "error": "invalid_state", "error_description": ""}
but "vent" returns a 200 but with the following: {"response": {"reason": "unknown state requested: ", "result": false}}
. Results seem to be the same with and without "percent" provided.
I'm definitely working on a car that has a panosunroof. I'm not sure it should make any difference, but the car is about 2 weeks out from delivery so it has the newest hardware. When I do a data_request/vehicle_state on the vehicle, I get the following back (among other parts): "sun_roof_installed": 2,"sun_roof_percent_open": 0,"sun_roof_state": "unknown",
Does anyone know of any differences in the API for the sunroof? Are there other combinations of parameters that anyone has had any success with.
Thanks so much for any help you can give!
I notice that both open_frunk and open_trunk have which_trunk: "rear".
These two commands don't seem to work, nor may I get them working per the API docs in CURL. Other commands like opening and closing the Pano Roof work fine.
irb(main):012:0> s.open_trunk
=> #<HTTParty::Response:0x7ff2b2824310 parsed_response={"response"=>nil, "error"=>"invalid_command", "error_description"=>""}, @response=#<Net::HTTPBadRequest 400 Bad Request readbody=true>, @headers={"server"=>["nginx"], "date"=>["Tue, 12 Jan 2016 15:29:34 GMT"], "content-type"=>["application/json; charset=utf-8"], "content-length"=>["66"], "connection"=>["close"], "status"=>["400 Bad Request"], "x-ua-compatible"=>["IE=Edge,chrome=1"], "cache-control"=>["no-cache"], "x-request-id"=>["4d67c7e7de471b6e7f6e4f9d3e75c3cc"], "x-runtime"=>["0.239390"]}>
irb(main):013:0> s.open_frunk
=> #<HTTParty::Response:0x7ff2b322b8e0 parsed_response={"response"=>nil, "error"=>"invalid_command", "error_description"=>""}, @response=#<Net::HTTPBadRequest 400 Bad Request readbody=true>, @headers={"server"=>["nginx"], "date"=>["Tue, 12 Jan 2016 15:29:44 GMT"], "content-type"=>["application/json; charset=utf-8"], "content-length"=>["66"], "connection"=>["close"], "status"=>["400 Bad Request"], "x-ua-compatible"=>["IE=Edge,chrome=1"], "cache-control"=>["no-cache"], "x-request-id"=>["36feb3214fa5850776928740b2e7f924"], "x-runtime"=>["0.047745"]}>
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.