This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

Help with Tesla Powerwall API V3
#19
(14.01.2022, 09:29)admin Wrote: The login part has been modified so the automated way no longer works. The only way is to manually get both tokens. See this for more info: https://teslascope.com/help/generating-tokens
But in this case another script is needed to handle token refresh because they have a limited lifetime. It can be automated but if the token cannot be refreshed then it has to be updated manually again.

i installed the Auth for Tesla app and get:
- Refresh Token
- Access Token

In the old situation it generates an Api Token and thats is used in the header.

How to use above codes in my lua code to get it working again?

Code:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
-- Load modules encdec = require('encdec') http = require('socket.http') mime = require('mime') ltn12 = require('ltn12') json = require('json') https = require('ssl.https') -- set credentials username = 'my@email.com' password = 'myPassword' client_id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -- default, do not change unless Tesla makes changes client_secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -- default, do not change unless Tesla makes changes -- all Tesla devices tesla =    {} -- car, vehicle_id tesla[1] = {'myCar1', 'myVehicleId'} CarID = tesla[1][2] -- run the script once, and look in the logs you will find a string called id_s this number is your vehicle ID, this should be replaced with the 123 in this field, remember to add "", then run script again, and you will get it to work! function GetToken()   function mt()     local ts, tu = os.microtime()     return ts .. '.' .. tu   end   function b64url(str)     return mime.b64(str):gsub('.', {       ['+'] = '-',       ['/'] = '_',       ['='] = '',     })   end   function encodeargs(t)     local res = {}     local esc = require('socket.url').escape     for k, v in pairs(t) do       res[ #res + 1 ] = esc(k) .. '=' .. esc(v)     end     return table.concat(res, '&')   end   code_verifier = encdec.sha512(mt()):sub(1, 86)   state = b64url(encdec.sha256(mt()):sub(1, 12))   code_challenge = b64url(code_verifier)   args = encodeargs({     client_id = 'ownerapi',     code_challenge = code_challenge,     code_challenge_method = 'S256',     redirect_uri = 'https://auth.tesla.com/void/callback',     response_type = 'code',     scope = 'openid email offline_access',     state = state,   })   url = 'https://auth.tesla.com/oauth2/v3/authorize?' .. args   res, code, headers = http.request(url)   if not res or code ~= 200 then     --log('request 1 failed', res, code)     return   end   postdata = {}   regexp = '<input type="hidden" name="([^"]+)" value="([^"]*)"'   for name, value in res:gmatch(regexp) do     postdata[ name ] = value   end   postdata.identity = username   postdata.credential = password   cookie = headers['Set-Cookie'] or headers['set-cookie'] or ''   body = encodeargs(postdata)   res, code, headers = http.request({     url = url,     method = 'POST',     source = ltn12.source.string(body),     headers = {       ['Content-Type'] = 'application/x-www-form-urlencoded',       ['Content-Length'] = #body,       ['Cookie'] = cookie,     }   })   if not res or code ~= 302 then     --log('request 2 failed', res, code)     return   end   hdr = headers.Location or headers.location   resp_code = hdr:match('code=([^&]+)')   body = json.encode({     grant_type = 'authorization_code',     client_id = 'ownerapi',     code = resp_code,     code_verifier = code_verifier,     redirect_uri = 'https://auth.tesla.com/void/callback',   })   resp = {}   res, code, headers = http.request({     url = 'https://auth.tesla.com/oauth2/v3/token',     method = 'POST',     source = ltn12.source.string(body),     sink = ltn12.sink.table(resp),     headers = {       ['Content-Type'] = 'application/json',       ['Accept'] = 'application/json',       ['Content-Length'] = #body,       ['User-Agent'] = 'Mozilla/5.0 (Linux; Android 9.0.0; VS985 4G Build/LRX21Y; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/58.0.3029.83 Mobile Safari/537.36',       ['X-Tesla-User-Agent'] = 'TeslaApp/3.4.4-350/fad4a582e/android/9.0.0',     }   })   if not res or code ~= 200 then     --log('request 3 failed', res, code)     return   end   resp = table.concat(resp)   resp = json.pdecode(resp)   bearer_token = resp.access_token   refresh_token = resp.refresh_token   body = json.encode({     grant_type = 'urn:ietf:params:oauth:grant-type:jwt-bearer',     client_id = client_id,     client_secret = client_secret,   })   resp = {}   res, code, headers = http.request({     url = 'https://owner-api.teslamotors.com/oauth/token',     method = 'POST',     source = ltn12.source.string(body),     sink = ltn12.sink.table(resp),     headers = {       ['Content-Type'] = 'application/json',       ['Authorization'] = 'Bearer ' .. bearer_token,       ['Content-Length'] = #body,     }   })   --print(res, code)   if not res or code ~= 200 then     --log('request 4 failed', res, code)     return   end   resp = table.concat(resp)   resp = json.pdecode(resp)   return resp.access_token end -- Request token if not API_Token then     API_Token = GetToken() end function RequestFromTesla(request)   request_url = 'https://owner-api.teslamotors.com/api/1/' .. request   local response_body = {}   local request_body = ""   local body, code, hdrs, stat = ssl.https.request{     url = request_url;     method = "GET";     headers =     {       ["Content-Type"] = "application/json";       ["Authorization"] = "Bearer " .. API_Token;     };     source = ltn12.source.string(request_body);     sink = ltn12.sink.table(response_body);   }   if code == 200 then     ret = table.concat(response_body)     ret = json.pdecode(ret)     return ret   else     API_Token = GetToken() -- request a new token   end end function WriteToTesla(request, request_body)   request_url = 'https://owner-api.teslamotors.com/api/1/' .. request   local response_body = {}   local content_length   if type(request_body) == "string" then     content_length = #request_body   else     request_body = ""   end   local body, code, hdrs, stat = ssl.https.request{     url = request_url;     method = "POST";     headers =     {       ["Content-Type"] = "application/json";       ["Authorization"] = "Bearer " .. API_Token;       ["Content-Length"] = content_length;     };     source = ltn12.source.string(request_body);     sink = ltn12.sink.table(response_body);   }   if code == 200 then     ret = table.concat(response_body)     ret = json.pdecode(ret)     return ret   else     API_Token = GetToken() -- request a new token   end end --------------------------------------------------------------------------------------- -- Get products function get_products()     products = RequestFromTesla('products')   return(products) -- Check here your product ID end -- Get vehicles function get_vehicles()     vehicles = RequestFromTesla('vehicles')     return(vehicles) -- Check here your Vehicles end -- Get onboarding data function get_onboarding_data()     onboarding_data = RequestFromTesla('users/onboarding_data')     return(onboarding_data) end -- Get vehicle data function get_vehicle_data()     vehicle_data = RequestFromTesla('vehicles/' .. CarID .. '/vehicle_data')     return(vehicle_data) end -- Wake up car function wake_up()     result = WriteToTesla('vehicles/' .. CarID .. '/wake_up')     debugLog(result) end -- Unlock car function door_unlock()     result = WriteToTesla('vehicles/' .. CarID .. '/command/door_unlock')     return(result) end -- Lock car function door_lock()   result = WriteToTesla('vehicles/' .. CarID .. '/command/door_lock')     return(result) end -- Honk horn function honk_horn()   result = WriteToTesla('vehicles/' .. CarID .. '/command/honk_horn')     return(result) end -- Flash lights function flash_lights()   result = WriteToTesla('vehicles/' .. CarID .. '/command/flash_lights')     return(result) end -- Autocondition start function auto_conditioning_start()     result = WriteToTesla('vehicles/' .. CarID .. '/command/auto_conditioning_start')     return(result) end -- Autocondition stop function auto_conditioning_stop()     result = WriteToTesla('vehicles/' .. CarID .. '/command/auto_conditioning_stop')     return(result) end -- Set temperature function set_temps(iDriverTemp,iPassengerTemp)     result = WriteToTesla('vehicles/' .. CarID .. '/command/set_temps?driver_temp='..iDriverTemp..'&passenger_temp='..iPassengerTemp)     return(result) end -- Charge port door open function charge_port_door_open()     result = WriteToTesla('vehicles/' .. CarID .. '/command/charge_port_door_open')     return(result) end -- Start charging function charge_start()     result = WriteToTesla('vehicles/' .. CarID .. '/command/charge_start')     return(result) end -- Stop charging function charge_stop()     result = WriteToTesla('vehicles/' .. CarID .. '/command/charge_stop')     return(result) end -- Open trunk rear function actuate_trunk()   result = WriteToTesla('vehicles/' .. CarID .. '/command/actuate_trunk', '{"which_trunk":"rear"}')     return(result) end -- Open trunk front function actuate_frunk()   result = WriteToTesla('vehicles/' .. CarID .. '/command/actuate_trunk', '{"which_trunk":"front"}')     return(result) end
Reply


Messages In This Thread
Help with Tesla Powerwall API V3 - by jamesng - 21.04.2021, 14:18
RE: Help with Tesla Powerwall API V3 - by gjniewenhuijse - 26.01.2022, 12:57

Forum Jump: