tesla_api 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 20e84c22651e2f1856d02fc5288277ec8ec512cc
4
+ data.tar.gz: b4a0471a5d0ca51c0974071b0ef526d7603a531c
5
+ SHA512:
6
+ metadata.gz: 6b0fc114f6cd257b6d52dbcc6aa6d3902a4241fd536cc39c75554ba96b5a88d56dc69e6076d15479c30e4133a1ca24573224daa054222dc04c7843a0a2f1ae17
7
+ data.tar.gz: f6f63dc83fd699d418c3f2702cf612f772c16a6a4980765a57d254eded2ded59a6cd065b3ed70762dc589464844720a2859d48b861bfa9b1c6b6ffd1da7e4902
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in tesla_api.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Tim Dorr
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # Tesla JSON API
2
+
3
+ [View Documentation](http://docs.timdorr.apiary.io/)
4
+
5
+ This is unofficial documentation of the Tesla Model S JSON API used by the iOS and Android apps.
6
+ The API provides functionality to monitor and control the Model S (and future Tesla vehicles) remotely.
7
+ The project provides both a documention of the API and a Ruby library to for accessing it.
8
+
9
+ ## Ruby Library
10
+
11
+ This gem provides a basic wrapper around the API to easily query and command the car remotely.
12
+ It also provides access to the streaming API and a means to process data coming from it.
13
+
14
+ ## Installation
15
+
16
+ Add this line to your application's Gemfile:
17
+ ```ruby
18
+ gem 'tesla_api'
19
+ ```
20
+
21
+ Or install it yourself:
22
+ ```sh
23
+ gem install tesla_api
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ Here's a quick example:
29
+
30
+ ```ruby
31
+ require 'tesla_api'
32
+
33
+ tesla_api = TeslaApi.new(email, password, client_id, client_secret)
34
+ model_s = tesla_api.vehicles.first
35
+
36
+ model_s.wake_up
37
+ model_s.auto_conditioning_start unless model_s.climate_state["is_auto_conditioning_on"]
38
+
39
+ model_s.set_charge_limit(90)
40
+ model_s.charge_start
41
+
42
+ charge_state = model_s.charge_state
43
+ puts "Your Model S is #{charge_state["charging_state"]} " +
44
+ "with a SOC of #{charge_state["battery_level"]}% " +
45
+ "and an estimate range of #{charge_state["est_battery_range"]} miles"
46
+ ```
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/apiary.apib ADDED
@@ -0,0 +1,433 @@
1
+ FORMAT: 1A
2
+ HOST: https://portal.vn.teslamotors.com
3
+
4
+ # Tesla Model S JSON API
5
+ This is unofficial documentation of the Tesla Model S JSON API used by the iOS and Android apps. It features functionality to monitor and control the Model S remotely.
6
+
7
+ # Group Authentication Flow
8
+ These endpoints handle login and session management
9
+
10
+ ## GET /login
11
+ Returns the login form. Sets a `_s_portal_session` cookie for the session
12
+ + Response 200
13
+
14
+ + Headers
15
+
16
+ Set-Cookie: _s_portal_session={cookie}; path=/; secure; HttpOnly
17
+
18
+ + Body
19
+
20
+ Login Screen HTML
21
+
22
+ ## POST /login
23
+ Performs the login. Takes in an plain text email and password, matching the owner's login from [http://teslamotors.com/mytesla](http://teslamotors.com/mytesla).
24
+
25
+ Sets a `user_credentials` cookie that expires in 3 months, which is passed along with all future requests to authenticate the user.
26
+
27
+ Redirects back to a dummy welcome page. This page is ignored by the smartphone app and can be ignored by your API client.
28
+ + Request (application/x-www-form-urlencoded)
29
+
30
+ + Body
31
+
32
+ user_session%5Bemail%5D=string&user_session%5Bpassword%5D=string
33
+
34
+ + Response 302
35
+
36
+ + Headers
37
+
38
+ Set-Cookie: _s_portal_session={cookie}; path=/; secure; HttpOnly
39
+ Set-Cookie: user_credentials=x; path=/; expires=Fri, 03-May-2013 03:01:54 GMT; secure; HttpOnly
40
+ Location: https://portal.vn.teslamotors.com/
41
+
42
+
43
+ + Body
44
+
45
+ Dummy Welcome Page
46
+
47
+
48
+ # Group Vehicle List
49
+ A logged in user can have multiple vehicles under their account. This resource is primarily responsible for listing the vehicles and the basic details about them.
50
+
51
+ Must have a `_s_portal_session` and `user_credentials` cookie set for all requests.
52
+
53
+ ## GET /vehicles
54
+ Retrieve a list of your owned vehicles (includes vehicles not yet shipped!)
55
+ + Response 200 (application/json)
56
+
57
+ + Body
58
+
59
+ [{
60
+ "color": null,
61
+ "display_name": null,
62
+ "id": 321,
63
+ "option_codes": "MS01,RENA,TM00,DRLH,PF00,BT85,PBCW,RFPO,WT19,IBMB,IDPB,TR00,SU01,SC01,TP01,AU01,CH00,HP00,PA00,PS00,AD02,X020,X025,X001,X003,X007,X011,X013",
64
+ "user_id": 123,
65
+ "vehicle_id": 1234567890,
66
+ "vin": "5YJSA1CN5CFP01657",
67
+ "tokens": ["x", "x"],
68
+ "state": "online"
69
+ }]
70
+
71
+
72
+ # Group Vehicle Status
73
+ These resources are read-only and determine the state of the vehicle's various sub-systems.
74
+
75
+ Must have a `_s_portal_session` and `user_credentials` cookie set for all requests.
76
+
77
+ ## GET /vehicles/{id}/mobile_enabled
78
+ Determines if mobile access to the vehicle is enabled.
79
+ + Parameters
80
+
81
+ + id (number) ... The ID number of the car
82
+
83
+ + Response 200 (application/json)
84
+
85
+ + Body
86
+
87
+ {
88
+ "reason":"",
89
+ "result":true
90
+ }
91
+
92
+ ## GET /vehicles/{id}/command/charge_state
93
+ Returns the state of charge in the battery.
94
+ + Parameters
95
+
96
+ + id (number) ... The ID number of the car
97
+
98
+ + Response 200 (application/json)
99
+
100
+ + Body
101
+
102
+ {
103
+ "charging_state": "Complete", // "Charging", ??
104
+ "charge_to_max_range": false, // current std/max-range setting
105
+ "max_range_charge_counter": 0,
106
+ "fast_charger_present": false, // connected to Supercharger?
107
+ "battery_range": 239.02, // rated miles
108
+ "est_battery_range": 155.79, // range estimated from recent driving
109
+ "ideal_battery_range": 275.09, // ideal miles
110
+ "battery_level": 91, // integer charge percentage
111
+ "battery_current": -0.6, // current flowing into battery
112
+ "charge_starting_range": null,
113
+ "charge_starting_soc": null,
114
+ "charger_voltage": 0, // only has value while charging
115
+ "charger_pilot_current": 40, // max current allowed by charger & adapter
116
+ "charger_actual_current": 0, // current actually being drawn
117
+ "charger_power": 0, // kW (rounded down) of charger
118
+ "time_to_full_charge": null, // valid only while charging
119
+ "charge_rate": -1.0, // float mi/hr charging or -1 if not charging
120
+ "charge_port_door_open": true
121
+ }
122
+
123
+ ## GET /vehicles/{id}/command/climate_state
124
+ Returns the current temperature and climate control state.
125
+ + Parameters
126
+
127
+ + id (number) ... The ID number of the car
128
+
129
+ + Response 200 (application/json)
130
+
131
+ + Body
132
+
133
+ {
134
+ "inside_temp": 17.0, // degC inside car
135
+ "outside_temp": 9.5, // degC outside car or null
136
+ "driver_temp_setting": 22.6, // degC of driver temperature setpoint
137
+ "passenger_temp_setting": 22.6, // degC of passenger temperature setpoint
138
+ "is_auto_conditioning_on": false, // apparently even if on
139
+ "is_front_defroster_on": null, // null or boolean as integer?
140
+ "is_rear_defroster_on": false,
141
+ "fan_status": 0 // fan speed 0-6 or null
142
+ }
143
+
144
+ ## GET /vehicles/{id}/command/drive_state
145
+ Returns the driving and position state of the vehicle.
146
+ + Parameters
147
+
148
+ + id (number) ... The ID number of the car
149
+
150
+ + Response 200 (application/json)
151
+
152
+ + Body
153
+
154
+ {
155
+ "shift_state": null, //
156
+ "speed": null, //
157
+ "latitude": 33.794839, // degrees N of equator
158
+ "longitude": -84.401593, // degrees W of the prime meridian
159
+ "heading": 4, // integer compass heading, 0-359
160
+ "gps_as_of": 1359863204 // Unix timestamp of GPS fix
161
+ }
162
+
163
+ ## GET /vehicles/{id}/command/gui_settings
164
+ Returns various information about the GUI settings of the car, such as unit format and range display.
165
+ + Parameters
166
+
167
+ + id (number) ... The ID number of the car
168
+
169
+ + Response 200 (application/json)
170
+
171
+ + Body
172
+
173
+ {
174
+ "gui_distance_units": "mi/hr",
175
+ "gui_temperature_units": "F",
176
+ "gui_charge_rate_units": "mi/hr",
177
+ "gui_24_hour_time": false,
178
+ "gui_range_display": "Rated"
179
+ }
180
+
181
+ ## GET /vehicles/{id}/command/vehicle_state
182
+ Returns the vehicle's physical state, such as which doors are open.
183
+ + Parameters
184
+
185
+ + id (number) ... The ID number of the car
186
+
187
+ + Response 200 (application/json)
188
+
189
+ + Body
190
+
191
+ {
192
+ "df": false, // driver's side front door open
193
+ "dr": false, // driver's side rear door open
194
+ "pf": false, // passenger's side front door open
195
+ "pr": false, // passenger's side rear door open
196
+ "ft": false, // front trunk is open
197
+ "rt": false, // rear trunk is open
198
+ "car_verson": "1.19.42", // car firmware version
199
+ "locked": true, // car is locked
200
+ "sun_roof_installed": false, // panoramic roof is installed
201
+ "sun_roof_state": "unknown",
202
+ "sun_roof_percent_open": 0, // null if not installed
203
+ "dark_rims": false, // gray rims installed
204
+ "wheel_type": "Base19", // wheel type installed
205
+ "has_spoiler": false, // spoiler is installed
206
+ "roof_color": "Colored", // "None" for panoramic roof
207
+ "perf_config": "Base"
208
+ }
209
+
210
+ # Group Vehicle Commands
211
+ These commands alter the vehicles state, and return result (true/false) to indicate success, and if failure reason contains the cause of failure.
212
+
213
+ Must have a `_s_portal_session` and `user_credentials` cookie set for all requests.
214
+
215
+ ## GET /vehicles/{id}/command/charge_port_door_open
216
+ Open the charge port.
217
+ + Parameters
218
+
219
+ + id (number) ... The ID number of the car
220
+
221
+ + Response 200 (application/json)
222
+
223
+ + Body
224
+
225
+ {
226
+ "result": false,
227
+ "reason": "failure reason"
228
+ }
229
+
230
+ ## GET /vehicles/{id}/command/charge_standard
231
+ Set the charge mode to standard (~90% under the new percentage system introduced in 4.5).
232
+ + Parameters
233
+
234
+ + id (number) ... The ID number of the car
235
+
236
+ + Response 200 (application/json)
237
+
238
+ + Body
239
+
240
+ {
241
+ "result": false,
242
+ "reason": "failure reason"
243
+ }
244
+
245
+ ## GET /vehicles/{id}/command/charge_max_range
246
+ Set the charge mode to max range (100% under the new percentage system introduced in 4.5).
247
+ + Parameters
248
+
249
+ + id (number) ... The ID number of the car
250
+
251
+ + Response 200 (application/json)
252
+
253
+ + Body
254
+
255
+ {
256
+ "result": false,
257
+ "reason": "failure reason"
258
+ }
259
+
260
+ ## GET /vehicles/{id}/command/set_charge_limit?percent={limit_value}
261
+ Set the charge limit to a custom percentage.
262
+ + Parameters
263
+
264
+ + id (number) ... The ID number of the car
265
+ + limit_value (number) ... The percentage value
266
+
267
+ + Response 200 (application/json)
268
+
269
+ + Body
270
+
271
+ {
272
+ "result": false,
273
+ "reason": "failure reason"
274
+ }
275
+
276
+ ## GET /vehicles/{id}/command/charge_start
277
+ Start charging.
278
+ + Parameters
279
+
280
+ + id (number) ... The ID number of the car
281
+
282
+ + Response 200 (application/json)
283
+
284
+ + Body
285
+
286
+ {
287
+ "result": false,
288
+ "reason": "failure reason" // "already started" if a charge is in progress
289
+ }
290
+
291
+ ## GET /vehicles/{id}/command/charge_stop
292
+ Stop charging.
293
+ + Parameters
294
+
295
+ + id (number) ... The ID number of the car
296
+
297
+ + Response 200 (application/json)
298
+
299
+ + Body
300
+
301
+ {
302
+ "result": false,
303
+ "reason": "failure reason" // "not_charging" if a charge was not in progress
304
+ }
305
+
306
+ ## GET /vehicles/{id}/command/flash_lights
307
+ Flash the lights once.
308
+ + Parameters
309
+
310
+ + id (number) ... The ID number of the car
311
+
312
+ + Response 200 (application/json)
313
+
314
+ + Body
315
+
316
+ {
317
+ "result": false,
318
+ "reason": "failure reason"
319
+ }
320
+
321
+ ## GET /vehicles/{id}/command/honk_horn
322
+ Honk the horn once.
323
+ + Parameters
324
+
325
+ + id (number) ... The ID number of the car
326
+
327
+ + Response 200 (application/json)
328
+
329
+ + Body
330
+
331
+ {
332
+ "result": false,
333
+ "reason": "failure reason"
334
+ }
335
+
336
+ ## GET /vehicles/{id}/command/door_unlock
337
+ Unlock the car's doors.
338
+ + Parameters
339
+
340
+ + id (number) ... The ID number of the car
341
+
342
+ + Response 200 (application/json)
343
+
344
+ + Body
345
+
346
+ {
347
+ "result": false,
348
+ "reason": "failure reason"
349
+ }
350
+
351
+ ## GET /vehicles/{id}/command/door_lock
352
+ Lock the car's doors.
353
+ + Parameters
354
+
355
+ + id (number) ... The ID number of the car
356
+
357
+ + Response 200 (application/json)
358
+
359
+ + Body
360
+
361
+ {
362
+ "result": false,
363
+ "reason": "failure reason"
364
+ }
365
+
366
+ ## GET /vehicles/{id}/command/set_temps?driver_temp={driver_degC}&passenger_temp={pass_degC}
367
+ Set the temperature target for the HVAC system.
368
+ + Parameters
369
+
370
+ + id (number) ... The ID number of the car
371
+ + driver_degC (number) ... The desired temperature on the driver's side in celcius.
372
+ + pass_degC (number) ... The desired temperature on the passenger's side in celcius.
373
+
374
+ + Response 200 (application/json)
375
+
376
+ + Body
377
+
378
+ {
379
+ "result": false,
380
+ "reason": "failure reason"
381
+ }
382
+
383
+ ## GET /vehicles/{id}/command/auto_conditioning_start
384
+ Start the HVAC system. Will cool or heat automatically, depending on set temperature.
385
+ + Parameters
386
+
387
+ + id (number) ... The ID number of the car
388
+
389
+ + Response 200 (application/json)
390
+
391
+ + Body
392
+
393
+ {
394
+ "result": false,
395
+ "reason": "failure reason"
396
+ }
397
+
398
+ ## GET /vehicles/{id}/command/auto_conditioning_stop
399
+ Stop the HVAC system.
400
+ + Parameters
401
+
402
+ + id (number) ... The ID number of the car
403
+
404
+ + Response 200 (application/json)
405
+
406
+ + Body
407
+
408
+ {
409
+ "result": false,
410
+ "reason": "failure reason"
411
+ }
412
+
413
+ ## GET /vehicles/{id}/command/sun_roof_control?state={state}
414
+ Controls the car's panoramic roof, if installed.
415
+ + Parameters
416
+
417
+ + id (number) ... The ID number of the car
418
+ + state (string)
419
+ The desired state of the panoramic roof. The approximate percent open values for each state are `open` = 100%, `close` = 0%, `comfort` = 80%, and `vent` = ~15%
420
+ + Values
421
+ + `open`
422
+ + `close`
423
+ + `comfort`
424
+ + `vent`
425
+
426
+ + Response 200 (application/json)
427
+
428
+ + Body
429
+
430
+ {
431
+ "result": false,
432
+ "reason": "failure reason"
433
+ }
data/lib/tesla_api.rb ADDED
@@ -0,0 +1,172 @@
1
+ require "tesla_api/version"
2
+
3
+ class TeslaApi
4
+ include HTTParty
5
+ base_uri "https://owner-api.teslamotors.com/api/1"
6
+ format :json
7
+
8
+ attr_reader :email
9
+
10
+ def initialize(email, password, client_id, client_secret)
11
+ @email = email
12
+ response = self.class.post(
13
+ "https://owner-api.teslamotors.com/oauth/token",
14
+ body: {
15
+ "grant_type" => "password",
16
+ "client_id" => client_id,
17
+ "client_secret" => client_secret,
18
+ "email" => email,
19
+ "password" => password
20
+ }
21
+ )
22
+ self.class.headers "Authorization" => "Bearer #{response["access_token"]}"
23
+ end
24
+
25
+ def vehicles
26
+ self.class.get("/vehicles")["response"].map { |v| Vehicle.new(self.class, email, v["id"], v) }
27
+ end
28
+
29
+ class Vehicle
30
+ attr_reader :api, :email, :id, :vehicle
31
+
32
+ def initialize(api, email, id, vehicle)
33
+ @api = api
34
+ @email = email
35
+ @id = id
36
+ @vehicle = vehicle
37
+ end
38
+
39
+ def [](key)
40
+ vehicle[key]
41
+ end
42
+
43
+ # State
44
+
45
+ def mobile_enabled
46
+ api.get("/vehicles/#{id}/mobile_enabled")["response"]
47
+ end
48
+
49
+ def charge_state
50
+ api.get("/vehicles/#{id}/data_request/charge_state")["response"]
51
+ end
52
+
53
+ def climate_state
54
+ api.get("/vehicles/#{id}/data_request/climate_state")["response"]
55
+ end
56
+
57
+ def drive_state
58
+ api.get("/vehicles/#{id}/data_request/drive_state")["response"]
59
+ end
60
+
61
+ def gui_settings
62
+ api.get("/vehicles/#{id}/data_request/gui_settings")["response"]
63
+ end
64
+
65
+ def vehicle_state
66
+ api.get("/vehicles/#{id}/data_request/vehicle_state")["response"]
67
+ end
68
+
69
+ # Commands
70
+
71
+ def wake_up
72
+ api.post("/vehicles/#{id}/wake_up")
73
+ end
74
+
75
+ def charge_port_door_open
76
+ api.post("/vehicles/#{id}/command/charge_port_door_open")
77
+ end
78
+
79
+ def charge_standard
80
+ api.post("/vehicles/#{id}/command/charge_standard")
81
+ end
82
+
83
+ def charge_max_range
84
+ api.post("/vehicles/#{id}/command/charge_max_range")
85
+ end
86
+
87
+ def set_charge_limit(percent)
88
+ api.post("/vehicles/#{id}/command/set_charge_limit", query: {state: "set", percent: percent})
89
+ end
90
+
91
+ def charge_start
92
+ api.post("/vehicles/#{id}/command/charge_start")
93
+ end
94
+
95
+ def charge_stop
96
+ api.post("/vehicles/#{id}/command/charge_stop")
97
+ end
98
+
99
+ def flash_lights
100
+ api.post("/vehicles/#{id}/command/flash_lights")
101
+ end
102
+
103
+ def honk_horn
104
+ api.post("/vehicles/#{id}/command/honk_horn")
105
+ end
106
+
107
+ def door_unlock
108
+ api.post("/vehicles/#{id}/command/door_unlock")
109
+ end
110
+
111
+ def door_lock
112
+ api.post("/vehicles/#{id}/command/door_lock")
113
+ end
114
+
115
+ def set_temps(driver_temp, passenger_temp)
116
+ api.post("/vehicles/#{id}/command/set_temps", query: {driver_temp: driver_temp, passenger_temp: passenger_temp})
117
+ end
118
+
119
+ def auto_conditioning_start
120
+ api.post("/vehicles/#{id}/command/auto_conditioning_start")
121
+ end
122
+
123
+ def auto_conditioning_stop
124
+ api.post("/vehicles/#{id}/command/auto_conditioning_stop")
125
+ end
126
+
127
+ def sun_roof_control(state)
128
+ api.post("/vehicles/#{id}/command/sun_roof_control", query: {state: state})
129
+ end
130
+
131
+ def sun_roof_move(percent)
132
+ api.post("/vehicles/#{id}/command/sun_roof_control", query: {state: "move", percent: percent})
133
+ end
134
+
135
+ # Streaming
136
+
137
+ def stream(&reciever)
138
+ EventMachine.run do
139
+ request = EventMachine::HttpRequest.new(
140
+ "https://streaming.vn.teslamotors.com/stream/#{self["vehicle_id"]}/" +
141
+ "?values=speed,odometer,soc,elevation,est_heading,est_lat,est_lng,power")
142
+
143
+ http = request.get(
144
+ head: {
145
+ "authorization" => [
146
+ email,
147
+ self["tokens"].first
148
+ ]
149
+ },
150
+ inactivity_timeout: 15)
151
+
152
+ http.stream do |chunk|
153
+ attributes = chunk.split(",")
154
+ reciever.call({
155
+ time: DateTime.strptime((attributes[0].to_i/1000).to_s, "%s"),
156
+ speed: attributes[1].to_f,
157
+ odometer: attributes[2].to_f,
158
+ soc: attributes[3].to_f,
159
+ elevation: attributes[4].to_f,
160
+ est_heading: attributes[5].to_f,
161
+ est_lat: attributes[6].to_f,
162
+ est_lng: attributes[7].to_f,
163
+ power: attributes[8].to_f
164
+ })
165
+ end
166
+
167
+ http.callback { EventMachine.stop }
168
+ http.errback { EventMachine.stop }
169
+ end
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,3 @@
1
+ module TeslaApi
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,44 @@
1
+ GET /login HTTP/1.1
2
+ Host: portal.vn.teslamotors.com
3
+ Connection: Keep-Alive
4
+ Accept-Encoding: gzip deflate
5
+
6
+
7
+ HTTP/1.1 200 OK
8
+ Content-Type: text/html; charset=utf-8
9
+ X-UA-Compatible: IE=Edge,chrome=1
10
+ ETag: "68693d0c80ee503a112cafc18a273525"
11
+ Cache-Control: max-age=0, private, must-revalidate
12
+ Set-Cookie: _s_portal_session=x; path=/; secure; HttpOnly
13
+ X-Request-Id: 80985fcba166592ed09cce956fd395d6
14
+ X-Runtime: 0.006161
15
+ Date: Sun, 03 Feb 2013 03:01:52 GMT
16
+ X-Rack-Cache: miss
17
+ Server: thin 1.4.1 codename Chromeo
18
+ Transfer-Encoding: chunked
19
+
20
+ 205
21
+ <!DOCTYPE html>
22
+ <html>
23
+ <head>
24
+ <title>Portal</title>
25
+ <script src="/assets/application-a5592d882a1bdc39d6b26c108a8ffbe0.js" type="text/javascript"></script>
26
+ <meta content="authenticity_token" name="csrf-param" />
27
+ <meta content="kOHBAsesbSMy0AJKsPC7f9aI/QgE9g4SxbUcfZAhvdg=" name="csrf-token" />
28
+ <meta name="csrf-token" content="kOHBAsesbSMy0AJKsPC7f9aI/QgE9g4SxbUcfZAhvdg=">
29
+
30
+ <link href='/images/favicon.ico' rel='shortcut icon'>
31
+
32
+ </head>
33
+ <body>
34
+ <header>
35
+ <li><a href="/login">Login</a></li>
36
+ </header>
37
+
38
+
39
+ </body>
40
+ </html>
41
+
42
+ 0
43
+
44
+
@@ -0,0 +1,29 @@
1
+ POST /login HTTP/1.1
2
+ Content-Length: 81
3
+ Content-Type: application/x-www-form-urlencoded; charset=UTF-8
4
+ Host: portal.vn.teslamotors.com
5
+ Connection: Keep-Alive
6
+ Cookie: _s_portal_session=BAh7B0kiD3Nlc3Npb25faWQGOgZFRkkiJWI2YzM0ZTJkMzZkMTk4ZWVkYjkzYzBiYWNmMzI3MTZkBjsAVEkiEF9jc3JmX3Rva2VuBjsARkkiMWtPSEJBc2VzYlNNeTBBSktzUEM3ZjlhSS9RZ0U5ZzRTeGJVY2ZaQWh2ZGc9BjsARg%3D%3D--da659682afba93065edfe2932903edc6eb16d0ac
7
+ Cookie2: $Version=1
8
+ Accept-Encoding: gzip deflate
9
+
10
+ user_session%5Bpassword%5D=xxx&user_session%5Bemail%5D=xxx%40xxx.com
11
+ HTTP/1.1 302 Found
12
+ Location: https://portal.vn.teslamotors.com/
13
+ Content-Type: text/html; charset=utf-8
14
+ X-UA-Compatible: IE=Edge,chrome=1
15
+ Cache-Control: no-cache
16
+ Set-Cookie: user_credentials=x; path=/; expires=Fri, 03-May-2013 03:01:54 GMT; secure; HttpOnly
17
+ Set-Cookie: _s_portal_session=x; path=/; secure; HttpOnly
18
+ X-Request-Id: a1c6e1dc7d2ba9c1c8cdec6ad536b2e4
19
+ X-Runtime: 1.129245
20
+ Date: Sun, 03 Feb 2013 03:01:54 GMT
21
+ X-Rack-Cache: invalidate, pass
22
+ Server: thin 1.4.1 codename Chromeo
23
+ Transfer-Encoding: chunked
24
+
25
+ 64
26
+ <html><body>You are being <a href="https://portal.vn.teslamotors.com/">redirected</a>.</body></html>
27
+ 0
28
+
29
+
data/logs/root.GET.log ADDED
@@ -0,0 +1,50 @@
1
+ GET / HTTP/1.1
2
+ Host: portal.vn.teslamotors.com
3
+ Connection: Keep-Alive
4
+ Cookie: _s_portal_session=x; user_credentials=x
5
+ Cookie2: $Version=1
6
+ Accept-Encoding: gzip deflate
7
+
8
+
9
+ HTTP/1.1 200 OK
10
+ Content-Type: text/html; charset=utf-8
11
+ X-UA-Compatible: IE=Edge,chrome=1
12
+ ETag: "389b2980d80c9fac569172b31c06dddb"
13
+ Cache-Control: must-revalidate, private, max-age=0
14
+ Set-Cookie: _s_portal_session=x; path=/; secure; HttpOnly
15
+ X-Request-Id: 2c54d0edded8b93de51a3cbf8a5dd3e9
16
+ X-Runtime: 0.007121
17
+ Date: Sun, 03 Feb 2013 03:01:54 GMT
18
+ X-Rack-Cache: miss
19
+ Server: thin 1.4.1 codename Chromeo
20
+ Transfer-Encoding: chunked
21
+
22
+ 249
23
+ <!DOCTYPE html>
24
+ <html>
25
+ <head>
26
+ <title>Portal</title>
27
+ <script src="/assets/application-a5592d882a1bdc39d6b26c108a8ffbe0.js" type="text/javascript"></script>
28
+ <meta content="authenticity_token" name="csrf-param" />
29
+ <meta content="6/1QjgCk7xTyDJGAK8xIpCNAShD8a6NSco4rbEyz6bw=" name="csrf-token" />
30
+ <meta name="csrf-token" content="6/1QjgCk7xTyDJGAK8xIpCNAShD8a6NSco4rbEyz6bw=">
31
+
32
+ <link href='/images/favicon.ico' rel='shortcut icon'>
33
+
34
+ </head>
35
+ <body>
36
+ <header>
37
+
38
+ <li>
39
+ <a href="/logout" data-method="delete" rel="nofollow">Logout</a>
40
+ </li>
41
+ </header>
42
+
43
+ Welcome to the portal app.
44
+
45
+ </body>
46
+ </html>
47
+
48
+ 0
49
+
50
+
data/tesla_api.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'tesla_api/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "tesla_api"
7
+ spec.version = TeslaApi::VERSION
8
+ spec.authors = ["Tim Dorr"]
9
+ spec.email = ["timdorr@timdorr.com"]
10
+ spec.summary = %q{A wrapper for the Tesla API}
11
+ spec.description = %q{Check the state of your Tesla Model S and issue basic commands. Stream data from the car's telematics system.}
12
+ spec.homepage = "https://github.com/timdorr/model-s-api"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.7"
21
+ spec.add_development_dependency "rake", "~> 10.0"
22
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tesla_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Tim Dorr
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: Check the state of your Tesla Model S and issue basic commands. Stream
42
+ data from the car's telematics system.
43
+ email:
44
+ - timdorr@timdorr.com
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - ".gitignore"
50
+ - Gemfile
51
+ - LICENSE.txt
52
+ - README.md
53
+ - Rakefile
54
+ - apiary.apib
55
+ - lib/tesla_api.rb
56
+ - lib/tesla_api/version.rb
57
+ - logs/login.GET.log
58
+ - logs/login.POST.log
59
+ - logs/root.GET.log
60
+ - tesla_api.gemspec
61
+ homepage: https://github.com/timdorr/model-s-api
62
+ licenses:
63
+ - MIT
64
+ metadata: {}
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project:
81
+ rubygems_version: 2.2.2
82
+ signing_key:
83
+ specification_version: 4
84
+ summary: A wrapper for the Tesla API
85
+ test_files: []