tesla-api 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.rdoc +40 -0
- data/Rakefile +10 -0
- data/fixtures/vcr_cassettes/charge_state.yml +134 -0
- data/fixtures/vcr_cassettes/climate_state.yml +134 -0
- data/fixtures/vcr_cassettes/connection.yml +91 -0
- data/fixtures/vcr_cassettes/drive_state.yml +134 -0
- data/fixtures/vcr_cassettes/gui_settings.yml +134 -0
- data/fixtures/vcr_cassettes/vehicle.yml +91 -0
- data/fixtures/vcr_cassettes/vehicle_state.yml +134 -0
- data/lib/tesla-api.rb +16 -0
- data/lib/tesla-api/charge_state.rb +87 -0
- data/lib/tesla-api/climate_state.rb +55 -0
- data/lib/tesla-api/connection.rb +58 -0
- data/lib/tesla-api/data.rb +52 -0
- data/lib/tesla-api/drive_state.rb +37 -0
- data/lib/tesla-api/errors.rb +41 -0
- data/lib/tesla-api/gui_settings.rb +34 -0
- data/lib/tesla-api/private_api.rb +157 -0
- data/lib/tesla-api/tesla_api.rb +4 -0
- data/lib/tesla-api/vehicle.rb +257 -0
- data/lib/tesla-api/vehicle_state.rb +92 -0
- data/lib/tesla-api/version.rb +4 -0
- data/tesla-api.gemspec +23 -0
- data/test/helper.rb +10 -0
- data/test/test_charge_state.rb +72 -0
- data/test/test_climate_state.rb +52 -0
- data/test/test_connection.rb +32 -0
- data/test/test_drive_state.rb +36 -0
- data/test/test_gui_settings.rb +36 -0
- data/test/test_vehicle.rb +32 -0
- data/test/test_vehicle_state.rb +80 -0
- metadata +135 -0
    
        data/lib/tesla-api.rb
    ADDED
    
    | @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            require 'json'
         | 
| 2 | 
            +
            require 'httpclient'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require "tesla-api/tesla_api"
         | 
| 5 | 
            +
            require "tesla-api/version"
         | 
| 6 | 
            +
            require "tesla-api/data"
         | 
| 7 | 
            +
            require "tesla-api/private_api"
         | 
| 8 | 
            +
            require "tesla-api/connection"
         | 
| 9 | 
            +
            require "tesla-api/charge_state"
         | 
| 10 | 
            +
            require "tesla-api/climate_state"
         | 
| 11 | 
            +
            require "tesla-api/drive_state"
         | 
| 12 | 
            +
            require "tesla-api/errors"
         | 
| 13 | 
            +
            require "tesla-api/gui_settings"
         | 
| 14 | 
            +
            require "tesla-api/vehicle"
         | 
| 15 | 
            +
            require "tesla-api/vehicle_state"
         | 
| 16 | 
            +
             | 
| @@ -0,0 +1,87 @@ | |
| 1 | 
            +
            module TeslaAPI
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              # Defines the current charge state of the vehicle
         | 
| 4 | 
            +
              class ChargeState < Data
         | 
| 5 | 
            +
                ##
         | 
| 6 | 
            +
                # :method: charging_state
         | 
| 7 | 
            +
                # Charging state ("Complete", "Charging")
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                ##
         | 
| 10 | 
            +
                # :method charging_to_max?
         | 
| 11 | 
            +
                # true if currently performing a range charge
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                ##
         | 
| 14 | 
            +
                # :method: battery_range_miles
         | 
| 15 | 
            +
                # Rated miles for the current charge
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                ##
         | 
| 18 | 
            +
                # :method: estimated_battry_range_miles
         | 
| 19 | 
            +
                # Range estimated from current driving
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                ##
         | 
| 22 | 
            +
                # :method: ideal_battery_range_miles
         | 
| 23 | 
            +
                # Ideal range for the current charge
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                ##
         | 
| 26 | 
            +
                # :method: battery_percentage
         | 
| 27 | 
            +
                # Percentage of battery charge
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                ##
         | 
| 30 | 
            +
                # :method: battery_current_flow
         | 
| 31 | 
            +
                # Current flowing into the battery
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                ##
         | 
| 34 | 
            +
                # :method: charger_voltage
         | 
| 35 | 
            +
                # Current voltage being used to charge battery
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                ##
         | 
| 38 | 
            +
                # :method: charger_pilot_amperage
         | 
| 39 | 
            +
                # Max amperage allowed by the charger
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                ##
         | 
| 42 | 
            +
                # :method: charger_actual_amperage
         | 
| 43 | 
            +
                # Current amperage being drawn into battery
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                ##
         | 
| 46 | 
            +
                # :method: charger_power
         | 
| 47 | 
            +
                # Kilowatt of charger (rounded down)
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                ##
         | 
| 50 | 
            +
                # :method: hours_to_full_charge
         | 
| 51 | 
            +
                # Hours remaining until the vehicle is fully charged
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                ##
         | 
| 54 | 
            +
                # :method: charge_rate_miles_per_hour
         | 
| 55 | 
            +
                # Miles of range being added per hour
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                ##
         | 
| 58 | 
            +
                # :method: charge_port_open?
         | 
| 59 | 
            +
                # true if the charge port is open
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                ##
         | 
| 62 | 
            +
                # :method: supercharging?
         | 
| 63 | 
            +
                # true if charging via a Tesla SuperCharger
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                def initialize(data) # :nodoc:
         | 
| 66 | 
            +
                  ivar_from_data("charging_state",               "charging_state",         data)
         | 
| 67 | 
            +
                  ivar_from_data("charging_to_max",              "charge_to_max_range",    data)
         | 
| 68 | 
            +
                  ivar_from_data("battery_range_miles",          "battery_range",          data)
         | 
| 69 | 
            +
                  ivar_from_data("estimated_battry_range_miles", "est_battery_range",      data)
         | 
| 70 | 
            +
                  ivar_from_data("ideal_battery_range_miles",    "ideal_battery_range",    data)
         | 
| 71 | 
            +
                  ivar_from_data("battery_percentage",           "battery_level",          data)
         | 
| 72 | 
            +
                  ivar_from_data("battery_current_flow",         "battery_current",        data)
         | 
| 73 | 
            +
                  ivar_from_data("charger_voltage",              "charger_voltage",        data)
         | 
| 74 | 
            +
                  ivar_from_data("charger_pilot_amperage",       "charger_pilot_current",  data)
         | 
| 75 | 
            +
                  ivar_from_data("charger_actual_amperage",      "charger_actual_current", data)
         | 
| 76 | 
            +
                  ivar_from_data("charger_power",                "charger_power",          data)
         | 
| 77 | 
            +
                  ivar_from_data("hours_to_full_charge",         "time_to_full_charge",    data)
         | 
| 78 | 
            +
                  ivar_from_data("charge_rate_miles_per_hour",   "charge_rate",            data)
         | 
| 79 | 
            +
                  ivar_from_data("charge_port_open",             "charge_port_door_open",  data)
         | 
| 80 | 
            +
                  ivar_from_data("supercharging",                "fast_charger_present",   data)
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                  @charging        = charging_state == "Charging"
         | 
| 83 | 
            +
                  @charge_complete = charging_state == "Complete"
         | 
| 84 | 
            +
                end
         | 
| 85 | 
            +
              end
         | 
| 86 | 
            +
            end
         | 
| 87 | 
            +
             | 
| @@ -0,0 +1,55 @@ | |
| 1 | 
            +
            module TeslaAPI
         | 
| 2 | 
            +
              # Defines the climate state of the vehicle.
         | 
| 3 | 
            +
              #
         | 
| 4 | 
            +
              class ClimateState < Data
         | 
| 5 | 
            +
                ##
         | 
| 6 | 
            +
                # :method: inside_temp_celcius
         | 
| 7 | 
            +
                # Temperature (celcius) inside the vehicle
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                ##
         | 
| 10 | 
            +
                # :method: outside_temp_celcius
         | 
| 11 | 
            +
                # Temperature (celcius) outside the vehicle
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                ##
         | 
| 14 | 
            +
                # :method: driver_temp_setting_celcius
         | 
| 15 | 
            +
                # Temperature (celcius) the driver has set
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                ##
         | 
| 18 | 
            +
                # :method: passenger_temp_setting_celcius
         | 
| 19 | 
            +
                # Temperature (celcius) the passenger has set
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                ##
         | 
| 22 | 
            +
                # :method: fan_speed
         | 
| 23 | 
            +
                # 0 to 6 (or nil)
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                ##
         | 
| 26 | 
            +
                # :method: auto_conditioning_on?
         | 
| 27 | 
            +
                # true if auto air conditioning is on
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                ##
         | 
| 30 | 
            +
                # :method: front_defroster_on?
         | 
| 31 | 
            +
                # true if the front defroster is on
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                ##
         | 
| 34 | 
            +
                # :method: rear_defroster_on?
         | 
| 35 | 
            +
                # true if the rear defroster is on
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                ##
         | 
| 38 | 
            +
                # :method: fan_on?
         | 
| 39 | 
            +
                # true if the fan is on
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                def initialize(data) # :nodoc:
         | 
| 42 | 
            +
                  ivar_from_data("inside_temp_celcius",            "inside_temp",            data)
         | 
| 43 | 
            +
                  ivar_from_data("outside_temp_celcius",           "outside_temp",           data)
         | 
| 44 | 
            +
                  ivar_from_data("driver_temp_setting_celcius",    "driver_temp_setting",    data)
         | 
| 45 | 
            +
                  ivar_from_data("passenger_temp_setting_celcius", "passenger_temp_setting", data)
         | 
| 46 | 
            +
                  ivar_from_data("fan_speed",                      "fan_speed",              data)
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  @auto_conditioning_on   = !!data["is_auto_conditioning_on"]
         | 
| 49 | 
            +
                  @front_defroster_on     = !!data["is_front_defroster_on"]
         | 
| 50 | 
            +
                  @rear_defroster_on      = !!data["is_rear_defroster_on"]
         | 
| 51 | 
            +
                  @fan_on                 = !data["fan_status"].nil?
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
              end
         | 
| 54 | 
            +
            end
         | 
| 55 | 
            +
             | 
| @@ -0,0 +1,58 @@ | |
| 1 | 
            +
            module TeslaAPI
         | 
| 2 | 
            +
              # Connection object to the Tesla Model S HTTP API endpoint.
         | 
| 3 | 
            +
              class Connection
         | 
| 4 | 
            +
                include PrivateAPI
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                # email address of logged in user
         | 
| 7 | 
            +
                attr_reader :email
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                # password of logged in user
         | 
| 10 | 
            +
                attr_reader :password
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                # Host for status/command related API
         | 
| 13 | 
            +
                HOST = "https://portal.vn.teslamotors.com"
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                # Host for streaming API
         | 
| 16 | 
            +
                STREAMING_HOST = "https://streaming.vn.teslamotors.com"
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                # Supply the email and password for login to teslamotors.com
         | 
| 19 | 
            +
                def initialize(email, password)
         | 
| 20 | 
            +
                  @email    = email
         | 
| 21 | 
            +
                  @password = password
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  @client = HTTPClient.new
         | 
| 24 | 
            +
                  @client.set_cookie_store("cookie.dat")
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                  login(email, password)
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                # Call to see all HTTP traffic to and from the API
         | 
| 30 | 
            +
                def debug!
         | 
| 31 | 
            +
                  @client.debug_dev = STDOUT
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                # Convenience method to return the first Vehicle
         | 
| 35 | 
            +
                def vehicle
         | 
| 36 | 
            +
                  vehicles.first
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                # Returns Vehicle objects for all vehicles the account contains
         | 
| 40 | 
            +
                def vehicles
         | 
| 41 | 
            +
                  @vehicles ||= begin
         | 
| 42 | 
            +
                    _, json = get_json("/vehicles")
         | 
| 43 | 
            +
                    json.map { |data| Vehicle.new(self, data) }
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                # Force the vehicles to reload (in case some of the data has changed)
         | 
| 48 | 
            +
                def reload!
         | 
| 49 | 
            +
                  @vehicles = nil
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                # Logged into the API
         | 
| 53 | 
            +
                def logged_in?
         | 
| 54 | 
            +
                  @logged_in
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
              end
         | 
| 57 | 
            +
            end
         | 
| 58 | 
            +
             | 
| @@ -0,0 +1,52 @@ | |
| 1 | 
            +
            module TeslaAPI
         | 
| 2 | 
            +
              # Base class for all data responses from the HTTP API
         | 
| 3 | 
            +
              #
         | 
| 4 | 
            +
              # Defines an instance_variable? method for each instance_variable defined allowing for
         | 
| 5 | 
            +
              # methods such as __________?
         | 
| 6 | 
            +
              #
         | 
| 7 | 
            +
              # Also overrides #inspect to elimiante the back reference to the connection object
         | 
| 8 | 
            +
              class Data
         | 
| 9 | 
            +
                def method_missing(method_name, *args, &block) # :nodoc:
         | 
| 10 | 
            +
                  if has_query_ivar_method?(method_name)
         | 
| 11 | 
            +
                    instance_variable_get(ivar_for_method_name(method_name))
         | 
| 12 | 
            +
                  else
         | 
| 13 | 
            +
                    super(symbol, *args, &block)
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def respond_to_missing?(method_name, include_private = false) # :nodoc:
         | 
| 18 | 
            +
                  has_query_ivar_method?(method_name) || super
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def inspect # :nodoc:
         | 
| 22 | 
            +
                  "#<#{self.class.name}:0x#{self.object_id.to_s(16)} #{inspect_ivars}>"
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def ivar_from_data(name, data_key, data) # :nodoc:
         | 
| 26 | 
            +
                  instance_variable_set("@#{name}".to_sym, data[data_key])
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  self.class.send(:attr_reader, name.to_sym)
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                protected
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                def ivar_for_method_name(method_name) # :nodoc:
         | 
| 34 | 
            +
                  "@#{method_name.to_s.gsub(/\?$/,"")}".to_sym
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                def has_query_ivar_method?(method_name) # :nodoc:
         | 
| 38 | 
            +
                  method = method_name.to_s
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  method =~ /(.+)\?/ && instance_variables.include?(ivar_for_method_name(method_name))
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                def inspect_ivars # :nodoc:
         | 
| 44 | 
            +
                  ivars_for_inspect.map { |ivar| "#{ivar}=#{instance_variable_get(ivar)}" }.join(" ")
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                def ivars_for_inspect # :nodoc:
         | 
| 48 | 
            +
                  (instance_variables - [:@tesla])
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
            end
         | 
| 52 | 
            +
             | 
| @@ -0,0 +1,37 @@ | |
| 1 | 
            +
            module TeslaAPI
         | 
| 2 | 
            +
              # Data defining the driving state of the the vehicle
         | 
| 3 | 
            +
              class DriveState < Data
         | 
| 4 | 
            +
                # Time when GPS data was recorded
         | 
| 5 | 
            +
                attr_reader :gps_timestamp
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                ##
         | 
| 8 | 
            +
                # :method: shift_state
         | 
| 9 | 
            +
                # Unknown
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                ##
         | 
| 12 | 
            +
                # :method: speed
         | 
| 13 | 
            +
                # Vehicle speed (units?)
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                ##
         | 
| 16 | 
            +
                # :method: latitude
         | 
| 17 | 
            +
                # Lattitude of vehicle
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                ##
         | 
| 20 | 
            +
                # :method: longitude
         | 
| 21 | 
            +
                # Longitude of vehicle
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                ##
         | 
| 24 | 
            +
                # :method: heading
         | 
| 25 | 
            +
                # Compass heading (0 to 360) degrees
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                def initialize(data) # :nodoc:
         | 
| 28 | 
            +
                  ivar_from_data("shift_state", "shift_state", data)
         | 
| 29 | 
            +
                  ivar_from_data("speed",       "speed",       data)
         | 
| 30 | 
            +
                  ivar_from_data("latitude",    "latitude",    data)
         | 
| 31 | 
            +
                  ivar_from_data("longitude",   "longitude",   data)
         | 
| 32 | 
            +
                  ivar_from_data("heading",     "heading",     data)
         | 
| 33 | 
            +
                  @gps_timestamp = Time.at(data["gps_as_of"])
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
            end
         | 
| 37 | 
            +
             | 
| @@ -0,0 +1,41 @@ | |
| 1 | 
            +
            module TeslaAPI
         | 
| 2 | 
            +
              # Exceptions thrown by the TeslaAPI
         | 
| 3 | 
            +
              module Errors
         | 
| 4 | 
            +
                # JSON cannot be parsed
         | 
| 5 | 
            +
                class InvalidJSON < StandardError
         | 
| 6 | 
            +
                  # JSON parsing error details
         | 
| 7 | 
            +
                  attr_reader :error
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  def initialize(error) # :nodoc:
         | 
| 10 | 
            +
                    @error = error
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  def to_s # :nodoc:
         | 
| 14 | 
            +
                    error.to_s
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                # Thrown when the action requires a logged in connection
         | 
| 19 | 
            +
                class NotLoggedIn < StandardError
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                # Thrown when the API returns a failure state
         | 
| 23 | 
            +
                class APIFailure < StandardError
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                # Thrown when the response is invalid (non 200-OK HTTP result)
         | 
| 27 | 
            +
                class InvalidResponse < StandardError
         | 
| 28 | 
            +
                  # Response object from httpclient
         | 
| 29 | 
            +
                  attr_reader :response
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  def initialize(response) # :nodoc:
         | 
| 32 | 
            +
                    @response = response
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  def to_s # :nodoc:
         | 
| 36 | 
            +
                    "Invalid Response: #{response.inspect}"
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
            end
         | 
| 41 | 
            +
             | 
| @@ -0,0 +1,34 @@ | |
| 1 | 
            +
            module TeslaAPI
         | 
| 2 | 
            +
              # Defines the current user settings for the vehicle's graphical display
         | 
| 3 | 
            +
              class GUISettings < Data
         | 
| 4 | 
            +
                ##
         | 
| 5 | 
            +
                # :method: gui_distance_units
         | 
| 6 | 
            +
                # Units ("mi/hr") for showing range
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                ##
         | 
| 9 | 
            +
                # :method: gui_temperature_units
         | 
| 10 | 
            +
                # Units ("F", "C") for showing temperaturs
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                ##
         | 
| 13 | 
            +
                # :method: gui_charge_rate_units
         | 
| 14 | 
            +
                # Units ("kW") for showing charge rage
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                ##
         | 
| 17 | 
            +
                # :method: gui_range_display
         | 
| 18 | 
            +
                # Units ("Rated", "Ideal") for showing range
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                # true if the UI show 24 hour time (e.g. 17:45)
         | 
| 21 | 
            +
                def gui_24_hour_time?
         | 
| 22 | 
            +
                  @gui_24_hour_time
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def initialize(data) # :nodoc:
         | 
| 26 | 
            +
                  ivar_from_data("gui_distance_units",    "gui_distance_units",    data)
         | 
| 27 | 
            +
                  ivar_from_data("gui_temperature_units", "gui_temperature_units", data)
         | 
| 28 | 
            +
                  ivar_from_data("gui_charge_rate_units", "gui_charge_rate_units", data)
         | 
| 29 | 
            +
                  ivar_from_data("gui_24_hour_time",      "gui_24_hour_time",      data)
         | 
| 30 | 
            +
                  ivar_from_data("gui_range_display",     "gui_range_display",     data)
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
            end
         | 
| 34 | 
            +
             | 
| @@ -0,0 +1,157 @@ | |
| 1 | 
            +
            module TeslaAPI
         | 
| 2 | 
            +
              module PrivateAPI # :nodoc:
         | 
| 3 | 
            +
                def login(email, password)
         | 
| 4 | 
            +
                  params = { "user_session[email]"    => email,
         | 
| 5 | 
            +
                             "user_session[password]" => password }
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                  response = @client.post(Connection::HOST + "/login", params)
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  @logged_in = (response.status_code == HTTP::Status::FOUND)
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def stream(vehicle)
         | 
| 13 | 
            +
                  raise "Doesn't work yet"
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  client = HTTPClient.new
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  uri = Connection::STREAMING_HOST + "/stream/#{vehicle.vehicle_id}/?values=speed,odometer,soc,elevation,est_heading,est_lat,est_lng,power,shift_state"
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  client.set_basic_auth(uri, streaming_login, vehicle.tokens.first)
         | 
| 20 | 
            +
                  client.get_content(uri) do |chunk|
         | 
| 21 | 
            +
                    p chunk
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def set_temperature!(vehicle, driver_degrees_celcius, passenger_degrees_celcius)
         | 
| 26 | 
            +
                  command!(vehicle, "set_temps", :query => { :driver_degrees_celcius    => driver_degrees_celcius,
         | 
| 27 | 
            +
                                                             :passenger_degrees_celcius => passenger_degrees_celcius })
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                def open_roof!(vehicle, state)
         | 
| 31 | 
            +
                  command!(vehicle, "sun_roof_control", :query => { :state => state })
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                def auto_conditioning_stop!(vehicle)
         | 
| 35 | 
            +
                  command!(vehicle, "auto_conditioning_stop")
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                def auto_conditioning_start!(vehicle)
         | 
| 39 | 
            +
                  command!(vehicle, "auto_conditioning_start")
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                def lock_door!(vehicle)
         | 
| 43 | 
            +
                  command!(vehicle, "door_lock")
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                def unlock_door!(vehicle)
         | 
| 47 | 
            +
                  command!(vehicle, "door_unlock")
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                def honk_horn!(vehicle)
         | 
| 51 | 
            +
                  command!(vehicle, "honk_horn")
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                def flash_lights!(vehicle)
         | 
| 55 | 
            +
                  command!(vehicle, "flash_lights")
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                def charge_stop!(vehicle)
         | 
| 59 | 
            +
                  command!(vehicle, "charge_stop")
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                def charge_start!(vehicle)
         | 
| 63 | 
            +
                  command!(vehicle, "charge_start")
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                def charge_max_range!(vehicle)
         | 
| 67 | 
            +
                  command!(vehicle, "charge_max_range")
         | 
| 68 | 
            +
                end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                def charge_standard!(vehicle)
         | 
| 71 | 
            +
                  command!(vehicle, "charge_standard")
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                def wake_up!(vehicle)
         | 
| 75 | 
            +
                  command!(vehicle, "wake_up")
         | 
| 76 | 
            +
                end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                def open_charge_port!(vehicle)
         | 
| 79 | 
            +
                  command!(vehicle, "charge_port_open")
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                def api_mobile_access?(vehicle)
         | 
| 83 | 
            +
                  _, json = get_json(command_url(vehicle, "mobile_enabled"))
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                  json["result"] == true
         | 
| 86 | 
            +
                end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
                def api_get_vehicle_state_for_vehicle(vehicle)
         | 
| 89 | 
            +
                  _, json = get_json(command_url(vehicle, "vehicle_state"))
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                  VehicleState.new(json)
         | 
| 92 | 
            +
                end
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                def api_gui_settings_for_vehicle(vehicle)
         | 
| 95 | 
            +
                  _, json = get_json(command_url(vehicle, "gui_settings"))
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                  GUISettings.new(json)
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                def api_drive_state_for_vehicle(vehicle)
         | 
| 101 | 
            +
                  _, json = get_json(command_url(vehicle, "drive_state"))
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                  DriveState.new(json)
         | 
| 104 | 
            +
                end
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                def api_climate_state_for_vehicle(vehicle)
         | 
| 107 | 
            +
                  _, json = get_json(command_url(vehicle, "climate_state"))
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                  ClimateState.new(json)
         | 
| 110 | 
            +
                end
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                def api_charge_state_for_vehicle(vehicle)
         | 
| 113 | 
            +
                  _, json = get_json(command_url(vehicle, "charge_state"))
         | 
| 114 | 
            +
             | 
| 115 | 
            +
                  ChargeState.new(json)
         | 
| 116 | 
            +
                end
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                private
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                def streaming_login
         | 
| 121 | 
            +
                  email.gsub("@","%")
         | 
| 122 | 
            +
                end
         | 
| 123 | 
            +
             | 
| 124 | 
            +
                def check_logged_in!
         | 
| 125 | 
            +
                  raise Errors::NotLoggedIn unless logged_in?
         | 
| 126 | 
            +
                end
         | 
| 127 | 
            +
             | 
| 128 | 
            +
                def command_url(vehicle, command_name)
         | 
| 129 | 
            +
                  "/vehicles/#{vehicle.id}/command/#{command_name}"
         | 
| 130 | 
            +
                end
         | 
| 131 | 
            +
             | 
| 132 | 
            +
                def command!(vehicle, command_name, options = {})
         | 
| 133 | 
            +
                  _, json = get_json(command_url(vehicle, command_name), options)
         | 
| 134 | 
            +
             | 
| 135 | 
            +
                  json["result"] ? json["result"] : raise(Errors::APIFailure.new(json["reason"]))
         | 
| 136 | 
            +
                end
         | 
| 137 | 
            +
             | 
| 138 | 
            +
                def get_json(uri, options = {})
         | 
| 139 | 
            +
                  check_logged_in!
         | 
| 140 | 
            +
             | 
| 141 | 
            +
                  response = get(uri, options)
         | 
| 142 | 
            +
             | 
| 143 | 
            +
                  [response, JSON.parse(response.body)]
         | 
| 144 | 
            +
                rescue JSON::ParserError => e
         | 
| 145 | 
            +
                  raise Errors::InvalidJSON.new(e)
         | 
| 146 | 
            +
                end
         | 
| 147 | 
            +
             | 
| 148 | 
            +
                def get(uri, options = {})
         | 
| 149 | 
            +
                  response = @client.get(Connection::HOST + uri, options)
         | 
| 150 | 
            +
             | 
| 151 | 
            +
                  raise Errors::InvalidResponse.new(response) unless response.status_code == HTTP::Status::OK
         | 
| 152 | 
            +
             | 
| 153 | 
            +
                  response
         | 
| 154 | 
            +
                end
         | 
| 155 | 
            +
              end
         | 
| 156 | 
            +
            end
         | 
| 157 | 
            +
             |