From 7bbdc322b76505afbde7024dd298318cfcb2fb80 Mon Sep 17 00:00:00 2001 From: Bobby Tamburrino Date: Wed, 13 Jan 2016 11:36:52 -0500 Subject: [PATCH 1/3] Updaing code to use OAuth2 API and some new features --- README.md | 2 + TeslaAPI.php | 114 ++++++++++++++++++++++++++++++++------------------- 2 files changed, 74 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 0e932ca..4491426 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ tesla-php Tesla PHP 5+ library for REST API Interaction. Based on: http://docs.timdorr.apiary.io/ +You will need to fill in the Client ID and Secret with a valid ID and Secret. Check the apiary docs for more info. + ## Usage diff --git a/TeslaAPI.php b/TeslaAPI.php index 83c33c7..3ad5080 100644 --- a/TeslaAPI.php +++ b/TeslaAPI.php @@ -8,9 +8,11 @@ class TeslaAPI { - private $url = "https://portal.vn.teslamotors.com"; - private $cookie_file = "/tmp/tesla-api-cookie"; + private $clientID = "{CLIENT ID}"; // Get current Client ID and Secret from apiary + private $clientSecret = "{CLIENT SECRET}"; + private $url = "https://owner-api.teslamotors.com"; private $id; + private $token; /** * @param $email @@ -20,9 +22,7 @@ class TeslaAPI public function __construct($email, $password, $id = 0) { $this->id = $id; - if (!is_file($this->cookie_file)) { - $this->api_auth($email, $password); - } + $this->api_auth($email, $password); $this->api_validate_auth(); } @@ -33,14 +33,15 @@ public function __construct($email, $password, $id = 0) private function api_auth($email, $password) { try { - $params = http_build_query(array('user_session' => array('email' => $email, 'password' => $password))); - $ch = curl_init($this->url . "/login"); - curl_setopt($ch, CURLOPT_COOKIEJAR, $this->cookie_file); + $params = http_build_query(array('grant_type' => 'password', 'client_id' => $this->clientID, 'client_secret' => $this->clientSecret, 'email' => $email, 'password' => $password)); + $ch = curl_init($this->url . "/oauth/token"); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $params); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array("Accept: application/json")); $output = curl_exec($ch); + $data = json_decode($output, true); + $this->token = $data['access_token']; } catch (Exception $e) { die('API Auth Failed! Exception: ' . $e); } @@ -55,25 +56,21 @@ private function api_auth($email, $password) public function api_call($command = "", $params = array()) { if (empty($command)) { - $api_url = $this->url . "/vehicles"; + $api_url = $this->url . "/api/1/vehicles"; } else { - if ($command === "mobile_enabled") { - $api_url = $this->url . "/vehicles/" . $this->id . "/mobile_enabled"; + if (!count($params)) { + $api_url = $this->url . "/api/1/vehicles/" . $this->id . $command; } else { - if (!count($params)) { - $api_url = $this->url . "/vehicles/" . $this->id . "/command/" . $command; - } else { - $http_params = http_build_query($params); - $api_url = $this->url . "/vehicles/" . $this->id . "/command/" . $command . "?" . $http_params; - } + $http_params = http_build_query($params); + $api_url = $this->url . "/api/1/vehicles/" . $this->id . $command . "?" . $http_params; } } try { $ch = curl_init($api_url); - curl_setopt($ch, CURLOPT_COOKIEFILE, $this->cookie_file); + curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_HTTPHEADER, array("Accept: application/json")); + curl_setopt($ch, CURLOPT_HTTPHEADER, array("Authorization: Bearer " . $this->token, "Accept: application/json")); $output = curl_exec($ch); } catch (Exception $e) { die("API Call Failed! Exception: " . $e); @@ -87,12 +84,11 @@ public function api_call($command = "", $params = array()) private function api_validate_auth() { $result = $this->api_call(); - if (isset($result[0]['id']) && $result[0]['id'] > 0) { + if (isset($result['response'][0]['id_s']) && $result['response'][0]['id_s'] > 0) { if ($this->id < 1) { - $this->id = $result[0]['id']; + $this->id = $result['response'][0]['id_s']; // id_s is a stringified version of id since the numeric id is now a BIGINT } } else { - unlink($this->cookie_file); Throw New Exception('auth fail.'); } } @@ -110,7 +106,7 @@ public function get_vehicles() */ public function get_mobile_enabled() { - return $this->api_call("mobile_enabled"); + return $this->api_call("/mobile_enabled"); } /** @@ -118,7 +114,7 @@ public function get_mobile_enabled() */ public function get_charge_state() { - return $this->api_call("charge_state"); + return $this->api_call("/data_request/charge_state"); } /** @@ -126,7 +122,7 @@ public function get_charge_state() */ public function get_climate_state() { - return $this->api_call("climate_state"); + return $this->api_call("/data_request/climate_state"); } /** @@ -134,7 +130,7 @@ public function get_climate_state() */ public function get_drive_state() { - return $this->api_call("drive_state"); + return $this->api_call("/data_request/drive_state"); } /** @@ -142,7 +138,7 @@ public function get_drive_state() */ public function get_gui_settings() { - return $this->api_call("gui_settings"); + return $this->api_call("/data_request/gui_settings"); } /** @@ -150,7 +146,15 @@ public function get_gui_settings() */ public function get_vehicle_state() { - return $this->api_call("vehicle_state"); + return $this->api_call("/data_request/vehicle_state"); + } + + /** + * @return mixed + */ + public function get_wake_up() + { + return $this->api_call("/wake_up"); } /** @@ -158,7 +162,7 @@ public function get_vehicle_state() */ public function get_charge_port_door_open() { - return $this->api_call("charge_port_door_open"); + return $this->api_call("/command/charge_port_door_open"); } /** @@ -166,7 +170,7 @@ public function get_charge_port_door_open() */ public function get_charge_standard() { - return $this->api_call("charge_standard"); + return $this->api_call("/command/charge_standard"); } /** @@ -174,7 +178,7 @@ public function get_charge_standard() */ public function get_charge_max_range() { - return $this->api_call("charge_max_range"); + return $this->api_call("/command/charge_max_range"); } /** @@ -182,7 +186,7 @@ public function get_charge_max_range() */ public function get_charge_start() { - return $this->api_call("charge_start"); + return $this->api_call("/command/charge_start"); } /** @@ -190,7 +194,7 @@ public function get_charge_start() */ public function get_charge_stop() { - return $this->api_call("charge_stop"); + return $this->api_call("/command/charge_stop"); } /** @@ -198,7 +202,7 @@ public function get_charge_stop() */ public function get_flash_lights() { - return $this->api_call("flash_lights"); + return $this->api_call("/command/flash_lights"); } /** @@ -206,7 +210,7 @@ public function get_flash_lights() */ public function get_honk_horn() { - return $this->api_call("honk_horn"); + return $this->api_call("/command/honk_horn"); } /** @@ -214,7 +218,7 @@ public function get_honk_horn() */ public function get_door_unlock() { - return $this->api_call("door_unlock"); + return $this->api_call("/command/door_unlock"); } /** @@ -222,7 +226,7 @@ public function get_door_unlock() */ public function get_door_lock() { - return $this->api_call("door_lock"); + return $this->api_call("/command/door_lock"); } /** @@ -230,7 +234,7 @@ public function get_door_lock() */ public function get_auto_conditioning_start() { - return $this->api_call("auto_conditioning_start"); + return $this->api_call("/command/auto_conditioning_start"); } /** @@ -238,7 +242,23 @@ public function get_auto_conditioning_start() */ public function get_auto_conditioning_stop() { - return $this->api_call("auto_conditioning_stop"); + return $this->api_call("/command/auto_conditioning_stop"); + } + + /** + * @return mixed + */ + public function get_remote_start() + { + return $this->api_call("/command/remote_start_drive", array('password' => $password)); + } + + /** + * @return mixed + */ + public function get_trunk_open() + { + return $this->api_call("/command/trunk_open"); } /** @@ -247,7 +267,17 @@ public function get_auto_conditioning_stop() public function get_google_map() { $drive_state = $this->get_drive_state(); - return "http://maps.google.com/?q=" . $drive_state['latitude'] . "," . $drive_state['longitude']; + return "http://maps.google.com/?q=" . $drive_state['response']['latitude'] . "," . $drive_state['response']['longitude']; + } + + /** + * @param $percent + * + * @return mixed + */ + public function set_charge_limit($percent = 75) + { + return $this->api_call("/command/set_charge_limit", array('percent' => $percent)); } /** @@ -258,7 +288,7 @@ public function get_google_map() */ public function set_set_temps($driver_temp, $pass_temp) { - return $this->api_call("set_temps", array('driver_temp' => $driver_temp, 'passenger_temp' => $pass_temp)); + return $this->api_call("/command/set_temps", array('driver_temp' => $driver_temp, 'passenger_temp' => $pass_temp)); } /** @@ -268,7 +298,7 @@ public function set_set_temps($driver_temp, $pass_temp) */ public function set_sun_roof_control($state = "close") { - return $this->api_call("sun_roof_control", array('state' => $state)); + return $this->api_call("/command/sun_roof_control", array('state' => $state)); } } From 0ae1b9b48cf6e0b6a2b87e639876292764243e24 Mon Sep 17 00:00:00 2001 From: Bobby Tamburrino Date: Wed, 13 Jan 2016 12:18:02 -0500 Subject: [PATCH 2/3] Making command and wake_up calls POST instead of GET --- TeslaAPI.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/TeslaAPI.php b/TeslaAPI.php index 3ad5080..e8f15ed 100644 --- a/TeslaAPI.php +++ b/TeslaAPI.php @@ -71,6 +71,10 @@ public function api_call($command = "", $params = array()) curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array("Authorization: Bearer " . $this->token, "Accept: application/json")); + if (preg_match("/(command|wake_up)/", $command)) { + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, null); + } $output = curl_exec($ch); } catch (Exception $e) { die("API Call Failed! Exception: " . $e); From 81e7ced8cd7654bc1f29a2db1a5e4f0b487a2169 Mon Sep 17 00:00:00 2001 From: Bobby Tamburrino Date: Mon, 18 Jan 2016 11:03:29 -0500 Subject: [PATCH 3/3] Fixing Remote Start to pull password from private class variable --- TeslaAPI.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TeslaAPI.php b/TeslaAPI.php index e8f15ed..53c0dfb 100644 --- a/TeslaAPI.php +++ b/TeslaAPI.php @@ -254,7 +254,7 @@ public function get_auto_conditioning_stop() */ public function get_remote_start() { - return $this->api_call("/command/remote_start_drive", array('password' => $password)); + return $this->api_call("/command/remote_start_drive", array('password' => $this->password)); } /**