tesla_api 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 20e84c22651e2f1856d02fc5288277ec8ec512cc
4
- data.tar.gz: b4a0471a5d0ca51c0974071b0ef526d7603a531c
3
+ metadata.gz: 45741a5c5b2afc5cd2e0eb6b2ecafa1115847868
4
+ data.tar.gz: 79c210bf38a56293ff3fc7261780eb84fcd87684
5
5
  SHA512:
6
- metadata.gz: 6b0fc114f6cd257b6d52dbcc6aa6d3902a4241fd536cc39c75554ba96b5a88d56dc69e6076d15479c30e4133a1ca24573224daa054222dc04c7843a0a2f1ae17
7
- data.tar.gz: f6f63dc83fd699d418c3f2702cf612f772c16a6a4980765a57d254eded2ded59a6cd065b3ed70762dc589464844720a2859d48b861bfa9b1c6b6ffd1da7e4902
6
+ metadata.gz: aec12640955ab16d5a77611e4bb66d34ff3084b362caf572372d59c8a2a7b484d8a46224d0a4f2dff0360d912b1e49f5eaf6c99a7c31ac4e4204814e10b207a7
7
+ data.tar.gz: 87ae5a2fac0c7ade54796a83d0c0eb6b87a3eddc20415f2c67c2c3959dda4e08ae38abe64e4052be0f3f4d5ee9656659a4dbc63aad79f8a5744880c65232444e
data/.gitignore CHANGED
@@ -12,3 +12,6 @@
12
12
  *.o
13
13
  *.a
14
14
  mkmf.log
15
+ .ruby-version
16
+ .ruby-gemset
17
+ .env
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format documentation
3
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.5
6
+ env:
7
+ global:
8
+ - TESLA_EMAIL=elon.musk@teslamotors.com
9
+ - TESLA_PASS=oilLOL
10
+ - TESLA_CLIENT_ID=1
11
+ - TESLA_CLIENT_SECRET=2
File without changes
data/README.md CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  [View Documentation](http://docs.timdorr.apiary.io/)
4
4
 
5
- This is unofficial documentation of the Tesla Model S JSON API used by the iOS and Android apps.
5
+ This is unofficial documentation of the Tesla JSON API used by the iOS and Android apps.
6
6
  The API provides functionality to monitor and control the Model S (and future Tesla vehicles) remotely.
7
7
  The project provides both a documention of the API and a Ruby library to for accessing it.
8
8
 
9
- ## Ruby Library
9
+ ## Ruby Gem [![Gem Version](https://img.shields.io/gem/v/tesla_api.svg)](http://rubygems.org/gems/tesla_api) [![Build Status](https://img.shields.io/travis/timdorr/model-s-api/master.svg)](https://travis-ci.org/timdorr/model-s-api)
10
10
 
11
11
  This gem provides a basic wrapper around the API to easily query and command the car remotely.
12
12
  It also provides access to the streaming API and a means to process data coming from it.
@@ -30,8 +30,8 @@ Here's a quick example:
30
30
  ```ruby
31
31
  require 'tesla_api'
32
32
 
33
- tesla_api = TeslaApi.new(email, password, client_id, client_secret)
34
- model_s = tesla_api.vehicles.first
33
+ tesla_api = TeslaApi::Client.new(email, password, client_id, client_secret)
34
+ model_s = tesla_api.vehicles.first # => <TeslaApi::Vehicle>
35
35
 
36
36
  model_s.wake_up
37
37
  model_s.auto_conditioning_start unless model_s.climate_state["is_auto_conditioning_on"]
@@ -44,3 +44,8 @@ puts "Your Model S is #{charge_state["charging_state"]} " +
44
44
  "with a SOC of #{charge_state["battery_level"]}% " +
45
45
  "and an estimate range of #{charge_state["est_battery_range"]} miles"
46
46
  ```
47
+
48
+ ## Copyright
49
+
50
+ Ruby portions are Copyright (c) 2014 Tim Dorr. Released under the terms of the
51
+ MIT license. See LICENSE for details.
data/Rakefile CHANGED
@@ -1,2 +1,8 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
2
3
 
4
+ RSpec::Core::RakeTask.new(:spec) do |task|
5
+ task.rspec_opts = ['--color', '--format', 'documentation', '--require', 'spec_helper']
6
+ end
7
+
8
+ task default: :spec
data/lib/tesla_api.rb CHANGED
@@ -1,172 +1,6 @@
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
1
+ require "httparty"
2
+ require "em-http-request"
82
3
 
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
4
+ require "tesla_api/version"
5
+ require "tesla_api/client"
6
+ require "tesla_api/vehicle"
@@ -0,0 +1,28 @@
1
+ module TeslaApi
2
+ class Client
3
+ include HTTParty
4
+ base_uri "https://owner-api.teslamotors.com/api/1"
5
+ format :json
6
+
7
+ attr_reader :email
8
+
9
+ def initialize(email, password, client_id, client_secret)
10
+ @email = email
11
+ response = self.class.post(
12
+ "https://owner-api.teslamotors.com/oauth/token",
13
+ body: {
14
+ "grant_type" => "password",
15
+ "client_id" => client_id,
16
+ "client_secret" => client_secret,
17
+ "email" => email,
18
+ "password" => password
19
+ }
20
+ )
21
+ self.class.headers "Authorization" => "Bearer #{response["access_token"]}"
22
+ end
23
+
24
+ def vehicles
25
+ self.class.get("/vehicles")["response"].map { |v| Vehicle.new(self.class, email, v["id"], v) }
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,145 @@
1
+ module TeslaApi
2
+ class Vehicle
3
+ attr_reader :api, :email, :id, :vehicle
4
+
5
+ def initialize(api, email, id, vehicle)
6
+ @api = api
7
+ @email = email
8
+ @id = id
9
+ @vehicle = vehicle
10
+ end
11
+
12
+ def [](key)
13
+ vehicle[key]
14
+ end
15
+
16
+ # State
17
+
18
+ def mobile_enabled
19
+ api.get("/vehicles/#{id}/mobile_enabled")["response"]
20
+ end
21
+
22
+ def charge_state
23
+ api.get("/vehicles/#{id}/data_request/charge_state")["response"]
24
+ end
25
+
26
+ def climate_state
27
+ api.get("/vehicles/#{id}/data_request/climate_state")["response"]
28
+ end
29
+
30
+ def drive_state
31
+ api.get("/vehicles/#{id}/data_request/drive_state")["response"]
32
+ end
33
+
34
+ def gui_settings
35
+ api.get("/vehicles/#{id}/data_request/gui_settings")["response"]
36
+ end
37
+
38
+ def vehicle_state
39
+ api.get("/vehicles/#{id}/data_request/vehicle_state")["response"]
40
+ end
41
+
42
+ # Commands
43
+
44
+ def wake_up
45
+ api.post("/vehicles/#{id}/wake_up")
46
+ end
47
+
48
+ def charge_port_door_open
49
+ api.post("/vehicles/#{id}/command/charge_port_door_open")
50
+ end
51
+
52
+ def charge_standard
53
+ api.post("/vehicles/#{id}/command/charge_standard")
54
+ end
55
+
56
+ def charge_max_range
57
+ api.post("/vehicles/#{id}/command/charge_max_range")
58
+ end
59
+
60
+ def set_charge_limit(percent)
61
+ api.post("/vehicles/#{id}/command/set_charge_limit", query: {state: "set", percent: percent})
62
+ end
63
+
64
+ def charge_start
65
+ api.post("/vehicles/#{id}/command/charge_start")
66
+ end
67
+
68
+ def charge_stop
69
+ api.post("/vehicles/#{id}/command/charge_stop")
70
+ end
71
+
72
+ def flash_lights
73
+ api.post("/vehicles/#{id}/command/flash_lights")
74
+ end
75
+
76
+ def honk_horn
77
+ api.post("/vehicles/#{id}/command/honk_horn")
78
+ end
79
+
80
+ def door_unlock
81
+ api.post("/vehicles/#{id}/command/door_unlock")
82
+ end
83
+
84
+ def door_lock
85
+ api.post("/vehicles/#{id}/command/door_lock")
86
+ end
87
+
88
+ def set_temps(driver_temp, passenger_temp)
89
+ api.post("/vehicles/#{id}/command/set_temps", query: {driver_temp: driver_temp, passenger_temp: passenger_temp})
90
+ end
91
+
92
+ def auto_conditioning_start
93
+ api.post("/vehicles/#{id}/command/auto_conditioning_start")
94
+ end
95
+
96
+ def auto_conditioning_stop
97
+ api.post("/vehicles/#{id}/command/auto_conditioning_stop")
98
+ end
99
+
100
+ def sun_roof_control(state)
101
+ api.post("/vehicles/#{id}/command/sun_roof_control", query: {state: state})
102
+ end
103
+
104
+ def sun_roof_move(percent)
105
+ api.post("/vehicles/#{id}/command/sun_roof_control", query: {state: "move", percent: percent})
106
+ end
107
+
108
+ # Streaming
109
+
110
+ def stream(&reciever)
111
+ EventMachine.run do
112
+ request = EventMachine::HttpRequest.new(
113
+ "https://streaming.vn.teslamotors.com/stream/#{self["vehicle_id"]}/" +
114
+ "?values=speed,odometer,soc,elevation,est_heading,est_lat,est_lng,power")
115
+
116
+ http = request.get(
117
+ head: {
118
+ "authorization" => [
119
+ email,
120
+ self["tokens"].first
121
+ ]
122
+ },
123
+ inactivity_timeout: 15)
124
+
125
+ http.stream do |chunk|
126
+ attributes = chunk.split(",")
127
+ reciever.call({
128
+ time: DateTime.strptime((attributes[0].to_i/1000).to_s, "%s"),
129
+ speed: attributes[1].to_f,
130
+ odometer: attributes[2].to_f,
131
+ soc: attributes[3].to_f,
132
+ elevation: attributes[4].to_f,
133
+ est_heading: attributes[5].to_f,
134
+ est_lat: attributes[6].to_f,
135
+ est_lng: attributes[7].to_f,
136
+ power: attributes[8].to_f
137
+ })
138
+ end
139
+
140
+ http.callback { EventMachine.stop }
141
+ http.errback { EventMachine.stop }
142
+ end
143
+ end
144
+ end
145
+ end
@@ -1,3 +1,3 @@
1
1
  module TeslaApi
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -0,0 +1,48 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://owner-api.teslamotors.com/oauth/token
6
+ body:
7
+ encoding: UTF-8
8
+ string: grant_type=password&client_id=<TESLA_CLIENT_ID>&client_secret=<TESLA_CLIENT_SECRET>&email=<TESLA_EMAIL>&password=<TESLA_PASS>
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - "*/*"
14
+ User-Agent:
15
+ - Ruby
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Server:
22
+ - nginx
23
+ Date:
24
+ - Mon, 15 Dec 2014 03:09:22 GMT
25
+ Content-Type:
26
+ - application/json; charset=utf-8
27
+ Transfer-Encoding:
28
+ - chunked
29
+ Connection:
30
+ - keep-alive
31
+ Status:
32
+ - 200 OK
33
+ Cache-Control:
34
+ - no-store
35
+ Pragma:
36
+ - no-cache
37
+ X-Ua-Compatible:
38
+ - IE=Edge,chrome=1
39
+ X-Request-Id:
40
+ - 349d563d345a9694c610770b743d3006
41
+ X-Runtime:
42
+ - '0.416152'
43
+ body:
44
+ encoding: UTF-8
45
+ string: '{"access_token":"1cba4845a8653d4b731440e9911d84304a179bd16a9ecbc9b649f2d8e0f6947e","token_type":"bearer","expires_in":7776000}'
46
+ http_version:
47
+ recorded_at: Mon, 15 Dec 2014 03:09:22 GMT
48
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,89 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://owner-api.teslamotors.com/oauth/token
6
+ body:
7
+ encoding: UTF-8
8
+ string: grant_type=password&client_id=<TESLA_CLIENT_ID>&client_secret=<TESLA_CLIENT_SECRET>&email=<TESLA_EMAIL>&password=<TESLA_PASS>
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - "*/*"
14
+ User-Agent:
15
+ - Ruby
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Server:
22
+ - nginx
23
+ Date:
24
+ - Mon, 15 Dec 2014 03:28:30 GMT
25
+ Content-Type:
26
+ - application/json; charset=utf-8
27
+ Transfer-Encoding:
28
+ - chunked
29
+ Connection:
30
+ - keep-alive
31
+ Status:
32
+ - 200 OK
33
+ Cache-Control:
34
+ - no-store
35
+ Pragma:
36
+ - no-cache
37
+ X-Ua-Compatible:
38
+ - IE=Edge,chrome=1
39
+ X-Request-Id:
40
+ - 2716f7fd5f4ee1239d044ddfba838d70
41
+ X-Runtime:
42
+ - '0.372092'
43
+ body:
44
+ encoding: UTF-8
45
+ string: '{"access_token":"53514fcfea416c9dd77b50d0a1c1dc681960002d23c22b1a9cf2681e8cbec8da","token_type":"bearer","expires_in":7776000}'
46
+ http_version:
47
+ recorded_at: Mon, 15 Dec 2014 03:28:30 GMT
48
+ - request:
49
+ method: get
50
+ uri: https://owner-api.teslamotors.com/api/1/vehicles
51
+ body:
52
+ encoding: US-ASCII
53
+ string: ''
54
+ headers:
55
+ Authorization:
56
+ - Bearer 53514fcfea416c9dd77b50d0a1c1dc681960002d23c22b1a9cf2681e8cbec8da
57
+ response:
58
+ status:
59
+ code: 200
60
+ message: OK
61
+ headers:
62
+ Server:
63
+ - nginx
64
+ Date:
65
+ - Mon, 15 Dec 2014 03:28:30 GMT
66
+ Content-Type:
67
+ - application/json; charset=utf-8
68
+ Content-Length:
69
+ - '446'
70
+ Connection:
71
+ - keep-alive
72
+ Status:
73
+ - 200 OK
74
+ X-Ua-Compatible:
75
+ - IE=Edge,chrome=1
76
+ Etag:
77
+ - '"4a35974adbecef7554d775e098548913"'
78
+ Cache-Control:
79
+ - max-age=0, private, must-revalidate
80
+ X-Request-Id:
81
+ - 59523c1d2611a93fa82e277ae4d97e87
82
+ X-Runtime:
83
+ - '0.289093'
84
+ body:
85
+ encoding: UTF-8
86
+ string: '{"response":[{"color":null,"display_name":"Nikola","id":1514029006966957156,"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,COUS","vehicle_id":490215852,"vin":"5YJSA1CN5CFP01657","tokens":["74bd32f47d3c8d9e","c244a90fbad06a65"],"state":"online","remote_start_enabled":true,"calendar_enabled":true,"notifications_enabled":true}],"count":1}'
87
+ http_version:
88
+ recorded_at: Mon, 15 Dec 2014 03:28:30 GMT
89
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe TeslaApi::Client do
4
+ subject(:tesla_api) { TeslaApi::Client.new(ENV["TESLA_EMAIL"], ENV["TESLA_PASS"], ENV["TESLA_CLIENT_ID"], ENV["TESLA_CLIENT_SECRET"]) }
5
+
6
+ describe "#initialize", vcr: { cassette_name: "client-initialize" } do
7
+ it { is_expected.to be_a(TeslaApi::Client) }
8
+
9
+ it "logs into the API" do
10
+ base_uri = URI.parse(tesla_api.class.base_uri)
11
+ expect(a_request(:post, "https://#{base_uri.host}/oauth/token")).to have_been_made.once
12
+ end
13
+
14
+ it "sets a Bearer token" do
15
+ expect(tesla_api.class.headers).to include({"Authorization" => /Bearer [a-z0-9]{32}/})
16
+ end
17
+ end
18
+
19
+ describe "#vehicles", vcr: {cassette_name: "client-vehicles"} do
20
+ it "lists the vehicles on the account" do
21
+ expect(tesla_api.vehicles).to include(TeslaApi::Vehicle)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,33 @@
1
+ require 'dotenv'
2
+ require 'vcr'
3
+ require 'webmock/rspec'
4
+
5
+ require 'tesla_api'
6
+
7
+ Dotenv.load
8
+
9
+ VCR.configure do |c|
10
+ c.cassette_library_dir = "spec/cassettes"
11
+ c.hook_into :webmock
12
+ c.default_cassette_options = {:record => :once}
13
+ c.configure_rspec_metadata!
14
+
15
+ c.define_cassette_placeholder("<TESLA_EMAIL>") { CGI::escape(ENV["TESLA_EMAIL"]) }
16
+ c.define_cassette_placeholder("<TESLA_PASS>") { ENV["TESLA_PASS"] }
17
+ c.define_cassette_placeholder("<TESLA_CLIENT_ID>") { ENV["TESLA_CLIENT_ID"] }
18
+ c.define_cassette_placeholder("<TESLA_CLIENT_SECRET>") { ENV["TESLA_CLIENT_SECRET"] }
19
+ end
20
+
21
+ RSpec.configure do |config|
22
+ config.expect_with :rspec do |expectations|
23
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
24
+ end
25
+
26
+ config.mock_with :rspec do |mocks|
27
+ mocks.verify_partial_doubles = true
28
+ end
29
+
30
+ config.disable_monkey_patching!
31
+ config.order = :random
32
+ Kernel.srand config.seed
33
+ end
data/tesla_api.gemspec CHANGED
@@ -17,6 +17,13 @@ Gem::Specification.new do |spec|
17
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
18
  spec.require_paths = ["lib"]
19
19
 
20
+ spec.add_dependency "httparty"
21
+ spec.add_dependency "em-http-request"
22
+
20
23
  spec.add_development_dependency "bundler", "~> 1.7"
21
24
  spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "rspec", "~> 3.1"
26
+ spec.add_development_dependency "vcr", "~> 2.9"
27
+ spec.add_development_dependency "webmock", "~> 1.20"
28
+ spec.add_development_dependency "dotenv", "~> 1.0"
22
29
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tesla_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Dorr
@@ -10,6 +10,34 @@ bindir: bin
10
10
  cert_chain: []
11
11
  date: 2014-12-15 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: em-http-request
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
13
41
  - !ruby/object:Gem::Dependency
14
42
  name: bundler
15
43
  requirement: !ruby/object:Gem::Requirement
@@ -38,6 +66,62 @@ dependencies:
38
66
  - - "~>"
39
67
  - !ruby/object:Gem::Version
40
68
  version: '10.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.1'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.1'
83
+ - !ruby/object:Gem::Dependency
84
+ name: vcr
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '2.9'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '2.9'
97
+ - !ruby/object:Gem::Dependency
98
+ name: webmock
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.20'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.20'
111
+ - !ruby/object:Gem::Dependency
112
+ name: dotenv
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.0'
41
125
  description: Check the state of your Tesla Model S and issue basic commands. Stream
42
126
  data from the car's telematics system.
43
127
  email:
@@ -47,16 +131,21 @@ extensions: []
47
131
  extra_rdoc_files: []
48
132
  files:
49
133
  - ".gitignore"
134
+ - ".rspec"
135
+ - ".travis.yml"
50
136
  - Gemfile
51
- - LICENSE.txt
137
+ - LICENSE
52
138
  - README.md
53
139
  - Rakefile
54
140
  - apiary.apib
55
141
  - lib/tesla_api.rb
142
+ - lib/tesla_api/client.rb
143
+ - lib/tesla_api/vehicle.rb
56
144
  - lib/tesla_api/version.rb
57
- - logs/login.GET.log
58
- - logs/login.POST.log
59
- - logs/root.GET.log
145
+ - spec/cassettes/client-initialize.yml
146
+ - spec/cassettes/client-vehicles.yml
147
+ - spec/lib/tesla_api/client_spec.rb
148
+ - spec/spec_helper.rb
60
149
  - tesla_api.gemspec
61
150
  homepage: https://github.com/timdorr/model-s-api
62
151
  licenses:
@@ -78,8 +167,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
78
167
  version: '0'
79
168
  requirements: []
80
169
  rubyforge_project:
81
- rubygems_version: 2.2.2
170
+ rubygems_version: 2.4.3
82
171
  signing_key:
83
172
  specification_version: 4
84
173
  summary: A wrapper for the Tesla API
85
- test_files: []
174
+ test_files:
175
+ - spec/cassettes/client-initialize.yml
176
+ - spec/cassettes/client-vehicles.yml
177
+ - spec/lib/tesla_api/client_spec.rb
178
+ - spec/spec_helper.rb
data/logs/login.GET.log DELETED
@@ -1,44 +0,0 @@
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
-
data/logs/login.POST.log DELETED
@@ -1,29 +0,0 @@
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 DELETED
@@ -1,50 +0,0 @@
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
-