tesla-api icon indicating copy to clipboard operation
tesla-api copied to clipboard

Add support for new Summon APIs

Open timdorr opened this issue 9 years ago • 103 comments

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.

timdorr avatar Jan 12 '16 16:01 timdorr

@timdorr I was updating a PHP library with the new info from your code and I ran into a stumbling block. While data_requests were working, anything that was a command (or wake_up) was returning a 404 error. Is it because of the Client ID and Secret that I'm using, which I got from your page? I'm able to do the commands from the native apps.

It looks like folks on TMC found the endpoints for the 7.1 features, but since I can't even honk my horn right now I haven't bothered to try them.

btamburrino avatar Jan 13 '16 17:01 btamburrino

@btamburrino Make sure you're issuing POST requests for the command endpoints. They are not GETs.

timdorr avatar Jan 13 '16 17:01 timdorr

@timdorr I tried that, they still returned 404's.

One thing I can report is that get all vehicles now returns id_s which is a stringified version of id. This is good because the id is now a BIGINT and that messes with some JSON decoders (like PHP's.)

EDIT: Nevermind. You also have to send a null POSTFIELDS.

btamburrino avatar Jan 13 '16 17:01 btamburrino

Did you figure out what the endpoints are for summon and homelink? I can't seem to find them anywhere on the web...

dcdspace avatar Feb 04 '16 21:02 dcdspace

I mentioned them here: http://www.teslamotorsclub.com/showthread.php/13410-Model-S-REST-API/page49?p=1337610&viewfull=1#post1337610

They both require keyfob presence near the car, so it's hard to test. I haven't dragged my laptop out to the garage yet.

timdorr avatar Feb 04 '16 21:02 timdorr

Just found out you can trick it by doing a keyless start and then using the associated APIs. I'll test this over the weekend. But I get the feeling Tesla is going to close up that hole pretty quickly (possibly even through the API itself...)

timdorr avatar Feb 05 '16 05:02 timdorr

Thanks I'll have to test it out tomorrow. Also you said "It looks like token is just your bluetooth device name", so is this token for the https://owner-api.teslamotors.com/api/1/vehicles/vehicle_id/trigger_homelink different from the token we normally use that is returned from the oauth request?

Also I know that the phone has to be near the car so once you fake lat/long parameters to just be the car's current position, you're saying after doing a keyless start it will work? Pretty cool...

dcdspace avatar Feb 05 '16 05:02 dcdspace

Yes, it's a separate token field. I traced the code back to the Bluetooth device name in the Android app.

And yeah, as long as the lat lon is within a certain distance (probably the magical 39 feet), it should work. It should be fine to simply duplicate the car's reported position.

timdorr avatar Feb 05 '16 05:02 timdorr

I see my issue was closed dupe with this one. I am unable to get homelink to work. Have you made progress by chance? I have a 2013 and always get reason:"unavailable" when I try to invoke. I am sending the current vehicle lat/long and phone BT name. I've tried enabling remote start first.

mseminatore avatar Apr 30 '16 01:04 mseminatore

I have a 2012, so I'm probably in the same boat. I'm pretty sure they group this off with Summon. I haven't made any attempts yet, though.

timdorr avatar Apr 30 '16 01:04 timdorr

I don't pass the BT device name and it works well for both summon and homelink. I instead just pass the same token I've been using for everything else.

dcdspace avatar Apr 30 '16 01:04 dcdspace

@dcdspace Do you have AP hardware?

mseminatore avatar Apr 30 '16 02:04 mseminatore

Yes

dcdspace avatar Apr 30 '16 06:04 dcdspace

Tesla must have updated their api because "trigger_homelink" no longer works, yet the native Tesla app can still do this. Any ideas?

dcdspace avatar Jun 20 '16 06:06 dcdspace

Are you attempting it with the fob within range? I think they make have closed the keyless driving loophole. As far as I know, the API itself hasn't changed.

timdorr avatar Jun 20 '16 13:06 timdorr

Yes the fob is in the car, and when I press the home link button in the Tesla app it works but my own api request no longer works. If they didn't update their API then what changed?

Also I tried to analyze their app with a proxy tool like Charles but the connection fails when I try that, any advice?

Dylan Diamond

On Jun 20, 2016, at 9:32 AM, Tim Dorr [email protected] wrote:

Are you attempting it with the fob within range? I think they make have closed the keyless driving loophole. As far as I know, the API itself hasn't changed.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

dcdspace avatar Jun 20 '16 17:06 dcdspace

@timdorr here is the explanation: https://teslamotorsclub.com/tmc/threads/model-s-rest-api.13410/page-80

They switched to web sockets apparently so it will be a bit harder to call summon and homelink.

dcdspace avatar Jun 21 '16 02:06 dcdspace

Looks like you open a standard Websocket connection to wss://streaming.vn.teslamotors.com/connect/{vehicle_id}.

From there, there is a JSON-based communication protocol with output commands and input results from the server: It has the rough format of

// Command from client
{"msg_type":"autopark:cmd_forward", "latitude":123.456, "longitude": 78.90}

// Response from server
{"msg_type":"autopark:cmd_result","cmd_type":"autopark:cmd_forward"","reason":"", "result":true}

So, it's pretty analogous to other parts of the standard HTTP API. I'm looking through all the commands right now and there are a bunch. Comments below have the details:

timdorr avatar Jun 21 '16 03:06 timdorr

Commands that can be received (msg_type -> arg1, arg2, ...) :

control:hello -> connection_timeout, autopark: {autopark_pause_timeout, autopark_stop_timeout, heartbeat_frequency}
control:goodbye -> reason
control:pong -> timestamp
autopark:status -> autopark_state
autopark:cmd_result -> cmd_type, reason, result
autopark:heartbeat_car -> timestamp
autopark:error -> error_type
homelink:status -> homelink_nearby (bool)
homelink:cmd_result -> command_type, failure_reason, result
vehicle_data:location -> latitude, longitude

timdorr avatar Jun 21 '16 03:06 timdorr

Commands that can be sent (msg_type -> arg1, arg2, ...):

control:ping -> timestamp
autopark:heartbeat_app -> timestamp
autopark:cmd_abort -> 
autopark:cmd_forward -> latitude, longitude
autopark:cmd_reverse -> latitude, longitude
homelink:cmd_trigger -> latitude, longitude

timdorr avatar Jun 21 '16 03:06 timdorr

For those really interested, here's the entire state machine they use for autopark related stuff (it's pretty complex): https://gist.github.com/timdorr/61834c6ada93d961e4646ea5fff6d7f7

timdorr avatar Jun 21 '16 03:06 timdorr

@timdorr Thanks so much! I just tested this and it works. A few questions I'm hoping you'll have the answers to:

I noticed that the headers that are sent with the initial websocket have a different Authorization value than normally. It is not Bearer: {token} but Basic with something else, so I'm wondering how to get that other value.

Do we need to include the Sec-WebSocket-Key value? If so where do we retrieve it?

Here is a screenshot of the headers with private info redacted. Thanks.

screen shot 2016-06-21 at 1 16 01 am

dcdspace avatar Jun 21 '16 05:06 dcdspace

Sec-WebSocket-Key is a mechanism to prevent proxies from caching any WebSocket stream being passed through them, by altering the data every time. It should be automatically handled by any WebSocket framework used to communicate. (In short, it's a SHA1 hash that is generated by taking the previous value, hashing it with a particular guid, and then Base64 encoding that)

The Authorization: Basic is the standard HTTP auth mechanism, a base64 encoding of username, followed by a colon (:) and then the password. The username is your Tesla account email address, the password being sent is the text/hex representation of 8 bytes , but I haven't been able to determine how that's generated yet. It is not a partial md5/sha1/sha256 hash of the tesla password or bearer token, nor a part of the bearer token itself. I'm assuming they're transforming the bearer token by some means to derive the password, but nothing obvious jumped out at me.

pdb0102 avatar Jun 21 '16 20:06 pdb0102

Correct. The header is in the format Authorization: Basic %{base64(token)}. The token comes from the vehicles endpoint in the tokens field. Same as the streaming data API.

timdorr avatar Jun 21 '16 20:06 timdorr

Duh, yeah. Forgot about the streaming tokens. But wouldn't the format be Authorization: Basic %{base64(email_addr ':' token)} ?

pdb0102 avatar Jun 21 '16 20:06 pdb0102

Ah, yes, you're right. It's Basic {base64({email}:{token})}

timdorr avatar Jun 21 '16 20:06 timdorr

Thanks it works now. Also what rate should we send the control:ping at?

dcdspace avatar Jun 21 '16 22:06 dcdspace

@dcdspace The Tesla implementation seems to send a ping every 5 seconds. The server will respond with a pong having the same time stamp as the ping you sent.

pdb0102 avatar Jun 21 '16 22:06 pdb0102

@pdb0102 Ok awesome. And when doing the autopark, should I send a heartbeat every 0.5 seconds? I have it going on a timer so that the user doesn't have to hold down a button so I'm hoping the car will stop on its own after a certain amount of time...?

dcdspace avatar Jun 21 '16 22:06 dcdspace

Look at whatever the heartbeat_frequency is in the control:hello response.

timdorr avatar Jun 21 '16 22:06 timdorr