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.
Discovered that some of the REST endpoints (like /vehicles/{id}/data_request/charge_state) are returning gzip compressed results as of firmware 2.9.x

I had copied the HTTP header properties from the mobile apps including
Code:
'Accept-Encoding': 'gzip,deflate'
but my client code did not properly handle responses with a compressed (binary) body. It does now. Thought others might want to know as well.

So far I only see this on the charge_state endpoint but it might be a sign of things to come.
 
Discovered that some of the REST endpoints (like /vehicles/{id}/data_request/charge_state) are returning gzip compressed results as of firmware 2.9.x

I had copied the HTTP header properties from the mobile apps including
Code:
'Accept-Encoding': 'gzip,deflate'
but my client code did not properly handle responses with a compressed (binary) body. It does now. Thought others might want to know as well.

So far I only see this on the charge_state endpoint but it might be a sign of things to come.

Pardon my ignorance when it comes to APIs and software development, but is that bad?

Jeff
 
I'm looking to install this with a solar system. I want to limit the car to only draw excess solar. This will be more important when i get my new charger but at the moment i want to limit the charge current. I can't find that in the documentation. Has anyone found this command?
 
I'm looking to install this with a solar system. I want to limit the car to only draw excess solar. This will be more important when i get my new charger but at the moment i want to limit the charge current. I can't find that in the documentation. Has anyone found this command?
I don't think there is currently a way in the API to limit the current draw but given rbergquist's post #1363 it looks as if that may be coming soon. For now you would have to use the car's screen to do that.

How big are your panels? I have 10kW of panels and assuming they were generating power at the rated output that is about half of the max power draw of my car as 240Vx80A = 20kW. So best case scenario would be that I would want to draw 40A. But that's assuming that I am at home when production is at its peak.

For now you might want to just use a scheduler to start at 10am and have the current setting at something like 20A, assuming that you have a 240V connection to your car and that you have 10kW of panels.

In my situation I sell all of the power back to the grid as in Ontario we get higher prices for solar than what we pay for electricity, plus I charge at night when rates are even lower.
 
What would be the reason for doing this? Aren't the results that are returned just a few bytes or so? Why would you care about compressing that?

charge_state is 1200 bytes, give or take, in JSON text form. That begins to add up quickly when you consider the number of cars (especially model 3) and what might be interacting with these cars (charging stations, home automation, mobile apps, etc.). Sure, right now it's probably limited if it's only the mobile app interacting with a small segment of 100,000 cars every other day or so - but there are many more applications that haven't been applied yet.

Even so, it's very simple to compress the data, just another line in the code (if accept_encoding includes gzip, compress(body)) - so why not?
 
charge_state is 1200 bytes, give or take, in JSON text form. That begins to add up quickly when you consider the number of cars (especially model 3) and what might be interacting with these cars (charging stations, home automation, mobile apps, etc.). Sure, right now it's probably limited if it's only the mobile app interacting with a small segment of 100,000 cars every other day or so - but there are many more applications that haven't been applied yet.

Even so, it's very simple to compress the data, just another line in the code (if accept_encoding includes gzip, compress(body)) - so why not?

Looks like they reverse proxy all requests through NGINX anyway so it can generate compressed responses automatically without them even having to code it in the Tesla server side apps.

Compression and Decompression | NGINX
 
Are people using other's libraries (node implementation, for instance), or have you mostly written your own?

I'm considering rewriting pytesla, since that's been abandoned for a while. I use Indigo Domotics for Mac and would like to make it a plugin. If anyone has any python implementations I can work off of, that would be helpful.
 
Are people using other's libraries (node implementation, for instance), or have you mostly written your own?

I'm considering rewriting pytesla, since that's been abandoned for a while. I use Indigo Domotics for Mac and would like to make it a plugin. If anyone has any python implementations I can work off of, that would be helpful.

I'm using hans' TeslaMS work, which puts the data into MongoDB - and I'm getting better at working with it every day.
 
I'm looking to install this with a solar system. I want to limit the car to only draw excess solar. This will be more important when i get my new charger but at the moment i want to limit the charge current. I can't find that in the documentation. Has anyone found this command?
Not aware of an API here, but I do know that another user was talking in a thread somewhere about modifying a HPWC to do that automatically by changing how much current it told the car it could supply and doing so on the fly to match his solar output. Maybe try some site searches and see if he ever got anywhere with it.
 
Are people using other's libraries (node implementation, for instance), or have you mostly written your own?

I'm considering rewriting pytesla, since that's been abandoned for a while. I use Indigo Domotics for Mac and would like to make it a plugin. If anyone has any python implementations I can work off of, that would be helpful.

jstenback/pytesla · GitHub is an updated version of pytesla that I spent some time hacking on, and adding some stuff to (streaming of events from the car primarily). Works fairly well.
 
My Quick & Dirty very short implementation in PHP

call:

$bash> php -q simpleteslaapi.php

Code:
<?php


class SimpleTeslaAPI {


    // Quick&Dirty Tesla API
    // V1.1
    // by [email protected]


    var $token;
    var $vehicleID;


    function SimpleTeslaAPI() {
        // !!!!!!!!! set token and vehicle_id (example out of mobile app "Remote S") !!!!!!!!!
        $this->token     = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
        $this->vehicleID = "xxxxxxxxxx";
    }


    private function curlexec($command,$mode="GET",$params=array()) {
        $url = 'https://owner-api.teslamotors.com/';


        $ch = curl_init();
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);


        $params['vehicle_id']=$this->vehicleID;


        if ( $mode == "POST" ) {
            if ( $command == "oauth/token" ) {
                curl_setopt($ch,CURLOPT_URL, $url.$command);
            } else {
                if ( $command == "wake_up" ) {
                    curl_setopt($ch,CURLOPT_URL, $url."api/1/vehicles/".$this->vehicleID."/wake_up");
                } else {
                    curl_setopt($ch,CURLOPT_URL, $url."api/1/vehicles/".$this->vehicleID."/command/".$command);
                }
                curl_setopt($ch,CURLOPT_HTTPHEADER, array("Authorization:Bearer ".$this->token) );
            }
            curl_setopt($ch,CURLOPT_POST, 1);
            curl_setopt($ch,CURLOPT_POSTFIELDS, $params);
        } else {
            if ( $command == "vehicles" ) {
                curl_setopt($ch,CURLOPT_URL, $url."api/1/vehicles");
            } else {
                curl_setopt($ch,CURLOPT_URL, $url."api/1/vehicles/".$this->vehicleID."/data_request/".$command."?".join("&",$params));
            }
            curl_setopt($ch,CURLOPT_HTTPHEADER, array("Authorization:Bearer ".$this->token) );
        }
        $result = curl_exec($ch);
        $rc=curl_getinfo($ch,CURLINFO_HTTP_CODE);


        curl_close($ch);


        return json_decode($result);
    }


    //basic functions
    function vehicles() {
        return $this->curlexec("vehicles","GET");
    }
    function wake_up() {
        return $this->curlexec("wake_up","POST");
    }


    //data-requests
    function charge_state() {
        return $this->curlexec("charge_state","GET");
    }
    function climate_state() {
        return $this->curlexec("climate_state","GET");
    }
    function drive_state() {
        return $this->curlexec("drive_state","GET");
    }
    function gui_settings() {
        return $this->curlexec("gui_settings","GET");
    }
    function vehicle_state() {
        return $this->curlexec("vehicle_state","GET");
    }


    // commands
    function charge_port_door_open() {
        return $this->curlexec("charge_port_door_open","POST");
    }
    function charge_standard() {
        return $this->curlexec("charge_standard","POST");
    }
    function charge_max_range() {
        return $this->curlexec("charge_max_range","POST");
    }
    function set_charge_limit($percent) {
        return $this->curlexec("set_charge_limit","POST",array("percent" => $percent ));
    }
    function charge_start() {
        return $this->curlexec("charge_start","POST");
    }
    function charge_stop() {
        return $this->curlexec("charge_stop","POST");
    }
    function flash_lights() {
        return $this->curlexec("flash_lights","POST");
    }
    function honk_horn() {
        return $this->curlexec("honk_horn","POST");
    }
    function door_unlock() {
        return $this->curlexec("door_unlock","POST");
    }
    function door_lock() {
        return $this->curlexec("door_lock","POST");
    }
    function set_temps($tempDriver, $tempPassenger) {
        return $this->curlexec("set_temps","POST",array("driver_temp" => $tempDriver,"passenger_temp" => $tempPassenger ));
    }
    function auto_conditioning_start() {
        return $this->curlexec("auto_conditioning_start","POST");
    }
    function auto_conditioning_stop() {
        return $this->curlexec("auto_conditioning_stop","POST");
    }
    function sun_roof_control_state($state) {
        return $this->curlexec("sun_roof_control","POST",array("state" => $state ));
    }
    function sun_roof_control_percent($percent) {
        return $this->curlexec("sun_roof_control","POST",array("state" => "move", "percent" => $percent ));
    }
    function remote_start_drive($password) {
        return $this->curlexec("remote_start_drive","POST",array("password" => $password ));
    }


    // deprecated
    function trunk_open() {
        return $this->curlexec("trunk_open","POST",array("which_trunk" => "rear" ));
    }
}




// Main


$tesla = new SimpleTeslaAPI();
print_r($tesla->honk_horn());
print_r($tesla->set_temps(22,22));
 
Hi,

this is my very own and very simpleTesla API implementation in PHP/cURL. It works fine with existing token and vehicle_id (got it from the mobile app "Remote S" !)

Code:
<?php

class SimpleTeslaAPI {


    // Quick&Dirty Tesla API
    // V1.1
    // by [email protected]


    var $token;
    var $vehicleID;


    function SimpleTeslaAPI() {
        // !!!!!!!!! set token and vehicle_id (example out of App "Remote S" !!!!!!!!!
        $this->token     = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
        $this->vehicleID = "xxxxxxxxxx";
    }


    private function curlexec($command,$mode="GET",$params=array()) {
        $url = 'https://owner-api.teslamotors.com/';


        $ch = curl_init();
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);


        $params['vehicle_id']=$this->vehicleID;


        if ( $mode == "POST" ) {
            if ( $command == "oauth/token" ) {
                curl_setopt($ch,CURLOPT_URL, $url.$command);
            } else {
                if ( $command == "wake_up" ) {
                    curl_setopt($ch,CURLOPT_URL, $url."api/1/vehicles/".$this->vehicleID."/wake_up");
                } else {
                    curl_setopt($ch,CURLOPT_URL, $url."api/1/vehicles/".$this->vehicleID."/command/".$command);
                }
                curl_setopt($ch,CURLOPT_HTTPHEADER, array("Authorization:Bearer ".$this->token) );
            }
            curl_setopt($ch,CURLOPT_POST, 1);
            curl_setopt($ch,CURLOPT_POSTFIELDS, $params);
        } else {
            if ( $command == "vehicles" ) {
                curl_setopt($ch,CURLOPT_URL, $url."api/1/vehicles");
            } else {
                curl_setopt($ch,CURLOPT_URL, $url."api/1/vehicles/".$this->vehicleID."/data_request/".$command."?".join("&",$params));
            }
            curl_setopt($ch,CURLOPT_HTTPHEADER, array("Authorization:Bearer ".$this->token) );
        }
        $result = curl_exec($ch);
        $rc=curl_getinfo($ch,CURLINFO_HTTP_CODE);


        curl_close($ch);


        return json_decode($result);
    }


    //basic functions
    function vehicles() {
        return $this->curlexec("vehicles","GET");
    }
    function wake_up() {
        return $this->curlexec("wake_up","POST");
    }


    //data-requests
    function charge_state() {
        return $this->curlexec("charge_state","GET");
    }
    function climate_state() {
        return $this->curlexec("climate_state","GET");
    }
    function drive_state() {
        return $this->curlexec("drive_state","GET");
    }
    function gui_settings() {
        return $this->curlexec("gui_settings","GET");
    }
    function vehicle_state() {
        return $this->curlexec("vehicle_state","GET");
    }




    // commands
    function charge_port_door_open() {
        return $this->curlexec("charge_port_door_open","POST");
    }
    function charge_standard() {
        return $this->curlexec("charge_standard","POST");
    }
    function charge_max_range() {
        return $this->curlexec("charge_max_range","POST");
    }
    function set_charge_limit($percent) {
        return $this->curlexec("set_charge_limit","POST",array("percent" => $percent ));
    }
    function charge_start() {
        return $this->curlexec("charge_start","POST");
    }
    function charge_stop() {
        return $this->curlexec("charge_stop","POST");
    }
    function flash_lights() {
        return $this->curlexec("flash_lights","POST");
    }
    function honk_horn() {
        return $this->curlexec("honk_horn","POST");
    }
    function door_unlock() {
        return $this->curlexec("door_unlock","POST");
    }
    function door_lock() {
        return $this->curlexec("door_lock","POST");
    }
    function set_temps($tempDriver, $tempPassenger) {
        return $this->curlexec("set_temps","POST",array("driver_temp" => $tempDriver,"passenger_temp" => $tempPassenger ));
    }
    function auto_conditioning_start() {
        return $this->curlexec("auto_conditioning_start","POST");
    }
    function auto_conditioning_stop() {
        return $this->curlexec("auto_conditioning_stop","POST");
    }
    function sun_roof_control_state($state) {
        return $this->curlexec("sun_roof_control","POST",array("state" => $state ));
    }
    function sun_roof_control_percent($percent) {
        return $this->curlexec("sun_roof_control","POST",array("state" => "move", "percent" => $percent ));
    }
    function remote_start_drive($password) {
        return $this->curlexec("remote_start_drive","POST",array("password" => $password ));
    }


    // deprecated
    function trunk_open() {
        return $this->curlexec("trunk_open","POST",array("which_trunk" => "rear" ));
    }
}




// Main


$tesla = new SimpleTeslaAPI();
print_r($tesla->honk_horn());
print_r($tesla->set_temps(22,22));