Last active
January 21, 2020 23:57
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 = "[email protected]" | |
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!" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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