LogicMachine Forum
Help with Tesla Powerwall API V3 - Printable Version

+- LogicMachine Forum (https://forum.logicmachine.net)
+-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1)
+--- Forum: Scripting (https://forum.logicmachine.net/forumdisplay.php?fid=8)
+--- Thread: Help with Tesla Powerwall API V3 (/showthread.php?tid=3308)

Pages: 1 2


Help with Tesla Powerwall API V3 - jamesng - 21.04.2021

Tesla recently changed its api to use v3 of the Tesla auth endpoint.

I've seen the V1 example script for logic machine, however the auth process seems a bit more complicated now!

An explanation of the auth process can be found here: https://tesla-api.timdorr.com/api-basics/authentication  and here https://teslamotorsclub.com/tmc/threads/tesla-owners-api-v3-enabled.219375/page-2#post-5308136

I've seen an example script written in Python

https://github.com/fkhera/powerwallCloud/blob/master/powerwallBackup.py#L132

Is anyone able to help me convert to lua to run on logic machine.


Specifically I'd like to automate a change in mode from 'backup-only' (which forces the Powerwall to charge from the Grid when rates are cheap) to 'self-powered' (which discharges the battery to power our home).

Many thanks in advanced

Kind Regards
James


RE: Help with Tesla Powerwall API V3 - gjniewenhuijse - 22.04.2021

follow +1


RE: Help with Tesla Powerwall API V3 - admin - 22.04.2021

If you can provide username/password via PM then I can create an example.


RE: Help with Tesla Powerwall API V3 - jamesng - 22.04.2021

Many thanks!


RE: Help with Tesla Powerwall API V3 - admin - 22.04.2021

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)



RE: Help with Tesla Powerwall API V3 - jamesng - 22.04.2021

Hi

Many thanks for the example. I've loaded it onto my Schneider SHAC (which runs an older version of the logic machine os) however I get the following error

script:36: attempt to call field 'sha512' (a nil value)

Kind Regards
James


RE: Help with Tesla Powerwall API V3 - admin - 23.04.2021

Try replacing these lines:
Code:
code_verifier = encdec.sha512(mt()):sub(1, 86) state = b64url(encdec.sha256(mt()):sub(1, 12)) code_challenge = b64url(code_verifier)

With this:
Code:
rnd = encdec.sha256(mt()) code_verifier = (rnd .. rnd):sub(1, 86) state = b64url(rnd:sub(1, 12)) code_challenge = b64url(code_verifier)



RE: Help with Tesla Powerwall API V3 - jamesng - 24.04.2021

Hi .. The script progresses a little further with this change, however still errors

Can you suggest what else I should update?

* arg: 1
* string: request 1 failed
* arg: 2
* nil
* arg: 3
* string: error:1409442E:lib(20):func(148):reason(1070)

Kind Regards
James


RE: Help with Tesla Powerwall API V3 - admin - 26.04.2021

This is due to outdated libraries in your firmware. Unfortunately it's not possible to update these libraries separately.
See if this works for you:
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 rnd = encdec.sha256(mt()) code_verifier = (rnd .. rnd):sub(1, 86) state = b64url(rnd: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, }) resp = {} url = 'https://auth.tesla.com/oauth2/v3/authorize?' .. args res, code, headers = http.request({   url = url,   sink = ltn12.sink.table(resp),   protocol = 'tlsv12', }) if not res or code ~= 200 then   log('request 1 failed', res, code)   return end postdata = {} regexp = '<input type="hidden" name="([^"]+)" value="([^"]*)"' resp = table.concat(resp) for name, value in resp: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),   protocol = 'tlsv12',   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),   protocol = 'tlsv12',   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),   protocol = 'tlsv12',   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)



RE: Help with Tesla Powerwall API V3 - jamesng - 26.04.2021

Generating the new auth_token is working on my SHAC (with the old libraries)

Thank you!!!


 I'd like to use this token to automate a change in mode from 'backup-only' (which forces the Powerwall to charge from the Grid when electricity rates are cheap) to 'self-powered' (which discharges the battery to power our home).



Could you please also help me convert the python code to pass this token back to the Tesla Powerwall to change the mode to Backup 

https://github.com/fkhera/powerwallCloud/blob/master/powerwallBackup.py#L132


Code:
## Set Powerwall Operation to Charge (Backup) or Discharge (self_consumption)     #  Pause PERHAPS WITH (self_consumption) w/ Current SoC as backup_reserve_percent     def operation_set(self, real_mode, backup_reserve_percent):         # auth_header = {'Authorization': 'Bearer ' + self.token}         payload = {"backup_reserve_percent": backup_reserve_percent}         #payload = json.dumps({"real_mode": real_mode, "backup_reserve_percent": backup_reserve_percent})         set_endpoint = '/backup'         set_url = self.energy_base_url + str(self.energy_site_id) + set_endpoint         print ("Setting Operation for Site Id: ", self.energy_site_id)         print ("Trying URL: ", set_url)         print ("Setting mode: " + json.dumps(payload))         try:             result = requests.post(set_url, json=payload, headers=self.auth_header, timeout=50)             print("Set result output: ", result.content)             if result.status_code == 201:                 print("Successfully changed reserve mode")         except HTTPError as err:             print("Error: {0}".format(err))         except Timeout as err:             print("Request timed out: {0}".format(err))#

Many thanks again

Kind Regards
James


RE: Help with Tesla Powerwall API V3 - admin - 28.04.2021

This should provide a list of products which id should be used in the next request. Change gateway URL and token as needed.
Code:
http = require('socket.http') ltn12 = require('ltn12') json = require('json') access_token = 'ABCDEF' url = 'https://192.168.1.1/api/1/products' resp = {} res, code, headers = http.request({   url = url,   method = 'GET',   sink = ltn12.sink.table(resp),   protocol = 'tlsv12',   headers = {     ['Authorization'] = 'Bearer ' .. access_token,   } }) resp = table.concat(resp) log(res, code, resp)

This request will set the battery reserve percent to 50. energy_site_id is the ID from the previous request.
Code:
http = require('socket.http') ltn12 = require('ltn12') json = require('json') access_token = 'ABCDEF' energy_site_id = '123456' backup_reserve_percent = 50 url = 'https://192.168.1.1/api/1/energy_sites/' .. energy_site_id .. '/backup' body = json.encode({   backup_reserve_percent = backup_reserve_percent, }) res, code, headers = http.request({   url = url,   method = 'POST',   source = ltn12.source.string(body),   protocol = 'tlsv12',   headers = {     ['Content-Type'] = 'application/json',     ['Content-Length'] = #body,     ['Authorization'] = 'Bearer ' .. access_token,   } }) log(res, code, headers)



RE: Help with Tesla Powerwall API V3 - jamesng - 29.04.2021

I've implemented the above and can report back that it's working!

The IP address in the URL above should be replaced with  'https://owner-api.teslamotors.com'


I'm still having a little trouble capturing the energy_site_id .. how does one traverse the returned table with a numeric (1) table name.


https://owner-api.teslamotors.com/api/1/products  returns data in the form 

Code:
* table: [response]   * table:   [1]     * table:     [site_name]       * string: Home Energy Gateway     [energy_site_id]       * string: xxxxxxx     [id]       * string: xxxx-xxx-xxxx-xxxx


which I'd normally process as follows

Code:
mydata = json.pdecode(table.concat(resp)) assetSiteD = mydata.response.1.energy_site_id


however the table name '1' in the above errors when I try to save the script

Code:
Lua syntax error at line 200: malformed number near '.1.energy_site_id'


How do I reference the value with a table name of 1?


Kind Regards
James


RE: Help with Tesla Powerwall API V3 - admin - 29.04.2021

Try this, or put quotes around 1 if it does not work.
Code:
assetSiteD = mydata.response[1].energy_site_id



RE: Help with Tesla Powerwall API V3 - jamesng - 29.04.2021

The [1] works ... the quotes did not.

Many thanks


RE: Help with Tesla Powerwall API V3 - gjniewenhuijse - 30.04.2021

yes it works.. great


RE: Help with Tesla Powerwall API V3 - mikeatlorne - 05.12.2021

hi there - I have a similar set up and need to use LUA - I am getting the following

trial access Tesla 2 05.12.2021 13:48:50
* arg: 1
* string: request 2 failed
* arg: 2
* string: <HTML><HEAD>
<TITLE>Access Denied</TITLE>
</HEAD><BODY>
<H1>Access Denied</H1>

You don't have permission to access "http://auth.tesla.com/oauth2/v3/authorize?" on this server.<P>
Reference #18.9444c717.1638672530.1633eb30
</BODY>
</HTML>

* arg: 3
* number: 403

any suggestions - with thanks


RE: Help with Tesla Powerwall API V3 - eilert - 13.01.2022

(05.12.2021, 03:03)mikeatlorne Wrote: hi there - I have a similar set up and need to use LUA - I am getting the following

trial access Tesla 2 05.12.2021 13:48:50
* arg: 1
  * string: request 2 failed
* arg: 2
  * string: <HTML><HEAD>
<TITLE>Access Denied</TITLE>
</HEAD><BODY>
<H1>Access Denied</H1>

You don't have permission to access "http://auth.tesla.com/oauth2/v3/authorize?" on this server.<P>
Reference #18.9444c717.1638672530.1633eb30
</BODY>
</HTML>

* arg: 3
  * number: 403

any suggestions - with thanks

Hi, anyone having the same problem or doing progress with this topic? Mine stops during the same step as above.

Best regards
Eilert Bjerkan
HW: LM5-M4(i.MX6), FW: 20200703


RE: Help with Tesla Powerwall API V3 - admin - 14.01.2022

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.


RE: Help with Tesla Powerwall API V3 - gjniewenhuijse - 26.01.2022

(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:
-- 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



RE: Help with Tesla Powerwall API V3 - admin - 26.01.2022

Specify API_Token = 'xyz' together with other credentials then you should be able to use the RequestFromTesla/WriteToTesla functions. Keep in mind that the token has expiration time and has to be refreshed.