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
#5
This should get you a request token and refresh token which can be used for further API calls. But this can stop working anytime if the login page structure changes since this example emulates user interaction with the login page.
Code:
username = 'user@domain.com' password = 'password' client_id = 'ID' client_secret = 'SECRET' encdec = require('encdec') http = require('socket.http') mime = require('mime') ltn12 = require('ltn12') json = require('json') 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) access_token = resp.access_token log(access_token)
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 admin - 22.04.2021, 12:32

Forum Jump: