Skip to content

Instantly share code, notes, and snippets.

@pkulak
Last active January 21, 2020 23:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save pkulak/f1a88b2a995881be0e4fc2681b577e55 to your computer and use it in GitHub Desktop.
Save pkulak/f1a88b2a995881be0e4fc2681b577e55 to your computer and use it in GitHub Desktop.
A quick script to turn on your Audi A3 E Tron's climate control remotely.
#!/usr/bin/env ruby
require 'unirest'
# Set these by going to etron.audiusa.com/web/aucwp/login once by hand and figuring them out
EMAIL = "me@example.com"
PASSWORD = "password"
ACCOUNT = 9999
PIN = 9999
# A really simple wrapper around Unirest so that we can have some cookie support
class CookieJar
def initialize
@jar = {}
end
def save_cookies(cookies)
(cookies || []).each do |c|
c = CGI::Cookie::parse(c).to_a
@jar[c[0][0]] = c[0][1][0]
end
end
def export
header = ""
@jar.each do |name, value|
header += "#{name}=#{value}; "
end
return {Cookie: header[0...-2]}
end
def inspect
return @jar.inspect
end
def post(url, options = {})
resp = Unirest.post(url, options.merge(headers: export))
save_cookies(resp.headers[:set_cookie])
if resp.headers[:location]
get(resp.headers[:location])
else
resp
end
end
def get(url)
resp = Unirest.get(url, {headers: export})
save_cookies(resp.headers[:set_cookie])
if resp.headers[:location]
get(resp.headers[:location])
else
resp
end
end
end
cookies = CookieJar.new
cookies.get "https://etron.audiusa.com/web/aucwp/login"
puts "Submitting username and password..."
cookies.post "https://etron.audiusa.com/web/aucwp/login?p_p_id=58&p_p_lifecycle=1&p_p_state=normal&p_p_mode=view&p_p_col_id=column-1&p_p_col_count=1&_58_struts_action=%2Flogin%2Flogin",
parameters: {
_58_formDate: Time.now.to_i * 1000,
_58_brand: "AUDI",
_58_saveLastPath: false,
_58_doActionAfterLogin: false,
_58_login: EMAIL,
_58_password: PASSWORD,
_58_cwpRemember: "on",
_58_userTimeZone: "America/Los_Angeles",
_58_chkEnabled: "on"}
puts "Submitting account number and pin..."
cookies.post "https://etron.audiusa.com/web/aucwp/login?p_p_id=58&p_p_lifecycle=2&p_p_state=normal&p_p_mode=view&p_p_cacheability=cacheLevelPage&p_p_col_id=column-1&p_p_col_count=1",
parameters: {
_58_accountNo: ACCOUNT,
_58_pin: PIN}
puts "Checking vehicle status..."
resp = cookies.post "https://etron.audiusa.com/group/aucwp/status?p_p_id=audidashboardportlet_WAR_audidashboardportlet&p_p_lifecycle=2&p_p_state=normal&p_p_mode=view&p_p_resource_id=GET_VEHICLE_STATUS&p_p_cacheability=cacheLevelPage&p_p_col_id=column-1&p_p_col_count=1"
data = resp.body
state_of_charge = data["StateOfCharge"].to_i
climate_on = data["isClimatisationOn"]
if state_of_charge <= 10
puts "Oh no! Battery needs to be more than 10% charged to turn on climate control!"
exit
end
if climate_on
puts "The climate control is already on, silly!"
exit
end
puts "\n"
puts "State of charge: #{state_of_charge}%"
puts "Plugged in: #{data["isChargingPlugConnected"]}"
puts "Charging: #{data["isBatteryCharging"]}"
puts "\n"
puts "Turning on climate control..."
resp = cookies.post 'https://etron.audiusa.com/group/aucwp/climate?p_p_id=etronclimateportlet_WAR_etronclimateportlet&p_p_lifecycle=2&p_p_state=normal&p_p_mode=view&p_p_resource_id=serveClimateTransaction&p_p_cacheability=cacheLevelPage&p_p_col_id=column-1&p_p_col_count=1',
parameters: {_etronclimateportlet_WAR_etronclimateportlet_climateOnOffIconStatus: true}
transactionId = resp.body["transactionId"]
responseCode = "FAILURE"
while responseCode == "FAILURE"
resp = cookies.post 'https://etron.audiusa.com/group/aucwp/climate?p_p_id=etronclimateportlet_WAR_etronclimateportlet&p_p_lifecycle=2&p_p_state=normal&p_p_mode=view&p_p_resource_id=pollClimateOnOff&p_p_cacheability=cacheLevelPage&p_p_col_id=column-1&p_p_col_count=1',
parameters: {
_etronclimateportlet_WAR_etronclimateportlet_climateTransactionId: transactionId,
_etronclimateportlet_WAR_etronclimateportlet_climateOnOffIconStatus: true
}
responseCode = resp.body["responseCode"]
sleep 3
end
puts "Climate control turned on!"
@pkulak
Copy link
Author

pkulak commented Nov 20, 2016

All you need to do is edit lines 4-7, make sure you have Ruby (plus the unirest library) installed, then run it like so:

ruby climate.rb

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment