Welcome to Tesla Motors Club
Discuss Tesla's Model S, Model 3, Model X, Model Y, Cybertruck, Roadster and More.
Register

Powerwall 2 Gateway API Documentation

This site may earn commission on affiliate links.
..I will still be using API calls as my ToU is a bit more complex than standard, just wanted to enable their ToU

Would you kindly elaborate on this for me?

My ToU in Tasmania is 7am-10am PEAK and 4pm-9pm PEAK. The rest being OFF_PEAK, and weekends also OFF_PEAK.
For which, except in high summer, I’m toggling to PEAK window via the app, twice a day. Arrgh!


Also, there is a knowledge gap in a subset of PW2 users, I figure that could be filled with a little how-to if anyone is interested.

Some of us IT infrastructure peeps do not have the coding and ‘runlet’ experience to take Vince Loschiavo excellent API documentation (vloschiavo/powerwall2) and plumb it into Telegraf/InfluxDB/Home-assistant.io (for example).

Does one create an executable shell script and automate via cron, or is there a more modern method?

TIA, Piers
 
Here's the raw list of calls I extracted from 1.34.3 on my Gateway:

Code:
"/api/customer/registration"
"/api/meters/aggregates"
"/api/site_info"
"/api/site_info/site_name"
"/api/sitemaster"
"/api/status"
"/api/system_status/grid_faults"
"/api/system_status/grid_status"
"/api/system_status/soe"
AUTH "/api/config"
AUTH "/api/config/completed"
AUTH "/api/customer"
AUTH "/api/logout"
AUTH "/api/meters"
AUTH "/api/meters/" + e + "/ct_config"
AUTH "/api/meters/readings"
AUTH "/api/meters/status"
AUTH "/api/networks"
AUTH "/api/operation"
AUTH "/api/powerwalls"
AUTH "/api/powerwalls/status"
AUTH "/api/site_info/grid_codes"
AUTH "/api/sitemaster/run"
AUTH "/api/sitemaster/stop"
AUTH "/api/system/networks/conn_tests"
AUTH "/api/system/testing"
AUTH DELETE "/api/meters/" + e + "/cts"
AUTH DELETE "/api/meters/" + t
AUTH DELETE "/api/networks/" + e + "/disconnect"
AUTH DELETE "/api/networks/" + e + "/remove"
AUTH DELETE "/api/system/testing"
AUTH POST "/api/customer"
AUTH POST "/api/customer/device"
AUTH POST "/api/customer/registration/emailed"
AUTH POST "/api/customer/registration/legal"
AUTH POST "/api/customer/registration/skip"
AUTH POST "/api/logging"
AUTH POST "/api/login/Basic"
AUTH POST "/api/meters"
AUTH POST "/api/meters/" + e + "/ct_config"
AUTH POST "/api/meters/" + e + "/invert_cts"
AUTH POST "/api/meters/" + i.serial + "/cts"
AUTH POST "/api/meters/" + n + "/commission"
AUTH POST "/api/meters/" + n + "/verify"
AUTH POST "/api/meters/detect_wired_meters"
AUTH POST "/api/networks/" + t + "/connect"
AUTH POST "/api/networks/disable_" + e
AUTH POST "/api/networks/edit_" + t
AUTH POST "/api/networks/enable_" + t
AUTH POST "/api/networks/scan_wifi"
AUTH POST "/api/operation"
AUTH POST "/api/password/generate"
AUTH POST "/api/powerwalls"
AUTH POST "/api/powerwalls/update"
AUTH POST "/api/site_info/grid_code"
AUTH POST "/api/site_info/offgrid"
AUTH POST "/api/site_info/site_name"
AUTH POST "/api/site_info/timezone"
AUTH POST "/api/sitemaster/run_for_commissioning"
AUTH POST "/api/system/networks/conn_tests"
AUTH POST "/api/system/networks/ping_test"
AUTH POST "/api/system/testing"
AUTH POST "/api/system/testing/PINV_TEST"
AUTH POST "/api/system/testing/charge"
POST "/api/password/change"
POST "/api/password/reset"
 
  • Informative
Reactions: cr0ntab
I don't think the local API has changed much (if at all) since I got my Powerwalls. Note that these are just the endpoints used to support the setup wizard. Until Tesla has a real interface on the Gateway to do all the configuration that's possible in the app, only a subset of the functionality will be available here.

I'm not sure how much of the server-side API for the Powerwalls has been reverse-engineered. The once-an-hour polling that the Gateway does for configuration changes makes use of that API kind of impractical, though.
 
Here's the raw list of calls I extracted from 1.34.3 on my Gateway:

Code:
"/api/customer/registration"
"/api/meters/aggregates"
"/api/site_info"
"/api/site_info/site_name"
"/api/sitemaster"
"/api/status"
"/api/system_status/grid_faults"
"/api/system_status/grid_status"
"/api/system_status/soe"
AUTH "/api/config"
AUTH "/api/config/completed"
AUTH "/api/customer"
AUTH "/api/logout"
AUTH "/api/meters"
AUTH "/api/meters/" + e + "/ct_config"
AUTH "/api/meters/readings"
AUTH "/api/meters/status"
AUTH "/api/networks"
AUTH "/api/operation"
AUTH "/api/powerwalls"
AUTH "/api/powerwalls/status"
AUTH "/api/site_info/grid_codes"
AUTH "/api/sitemaster/run"
AUTH "/api/sitemaster/stop"
AUTH "/api/system/networks/conn_tests"
AUTH "/api/system/testing"
AUTH DELETE "/api/meters/" + e + "/cts"
AUTH DELETE "/api/meters/" + t
AUTH DELETE "/api/networks/" + e + "/disconnect"
AUTH DELETE "/api/networks/" + e + "/remove"
AUTH DELETE "/api/system/testing"
AUTH POST "/api/customer"
AUTH POST "/api/customer/device"
AUTH POST "/api/customer/registration/emailed"
AUTH POST "/api/customer/registration/legal"
AUTH POST "/api/customer/registration/skip"
AUTH POST "/api/logging"
AUTH POST "/api/login/Basic"
AUTH POST "/api/meters"
AUTH POST "/api/meters/" + e + "/ct_config"
AUTH POST "/api/meters/" + e + "/invert_cts"
AUTH POST "/api/meters/" + i.serial + "/cts"
AUTH POST "/api/meters/" + n + "/commission"
AUTH POST "/api/meters/" + n + "/verify"
AUTH POST "/api/meters/detect_wired_meters"
AUTH POST "/api/networks/" + t + "/connect"
AUTH POST "/api/networks/disable_" + e
AUTH POST "/api/networks/edit_" + t
AUTH POST "/api/networks/enable_" + t
AUTH POST "/api/networks/scan_wifi"
AUTH POST "/api/operation"
AUTH POST "/api/password/generate"
AUTH POST "/api/powerwalls"
AUTH POST "/api/powerwalls/update"
AUTH POST "/api/site_info/grid_code"
AUTH POST "/api/site_info/offgrid"
AUTH POST "/api/site_info/site_name"
AUTH POST "/api/site_info/timezone"
AUTH POST "/api/sitemaster/run_for_commissioning"
AUTH POST "/api/system/networks/conn_tests"
AUTH POST "/api/system/networks/ping_test"
AUTH POST "/api/system/testing"
AUTH POST "/api/system/testing/PINV_TEST"
AUTH POST "/api/system/testing/charge"
POST "/api/password/change"
POST "/api/password/reset"

Woferry, do any of these reqests, to your knowledge, provide current voltage level and sine wave Hertz value? Being able to query up that information for the infamous 66 Hz bump when the circuit becomes islanded would useful...
 
Woferry, do any of these reqests, to your knowledge, provide current voltage level and sine wave Hertz value? Being able to query up that information for the infamous 66 Hz bump when the circuit becomes islanded would useful...
/api/meters/aggregates includes those. Here's a sample:


{
"site": {
"last_communication_time": "2019-05-08T15:52:50.489021579-07:00",
"instant_power": -4728.14990234375,
"instant_reactive_power": 111.89999961853027,
"instant_apparent_power": 4729.473872318975,
"frequency": 60,
"energy_exported": 7109714.548918119,
"energy_imported": 10740907.429195896,
"instant_average_voltage": 125.875,
"instant_total_current": 0,
"i_a_current": 0,
"i_b_current": 0,
"i_c_current": 0,
"timeout": 1500000000
},
"battery": {
"last_communication_time": "2019-05-08T15:52:50.490166902-07:00",
"instant_power": 730,
"instant_reactive_power": 0,
"instant_apparent_power": 730,
"frequency": 60.013999999999996,
"energy_exported": 1666960,
"energy_imported": 2107550,
"instant_average_voltage": 251.65,
"instant_total_current": -17.700000000000003,
"i_a_current": 0,
"i_b_current": 0,
"i_c_current": 0,
"timeout": 1500000000
},
"load": {
"last_communication_time": "2019-05-08T15:52:50.489021579-07:00",
"instant_power": 730.4965934209245,
"instant_reactive_power": -36.4131006955253,
"instant_apparent_power": 731.4035732082787,
"frequency": 60,
"energy_exported": 0,
"energy_imported": 15146371.921944445,
"instant_average_voltage": 125.875,
"instant_total_current": 5.803349302251634,
"i_a_current": 0,
"i_b_current": 0,
"i_c_current": 0,
"timeout": 1500000000
},
"solar": {
"last_communication_time": "2019-05-08T15:52:50.489140912-07:00",
"instant_power": 4698.6201171875,
"instant_reactive_power": -147.17000579833984,
"instant_apparent_power": 4700.924378911637,
"frequency": 60,
"energy_exported": 11956234.147228653,
"energy_imported": 465.1055619854691,
"instant_average_voltage": 125.86499786376953,
"instant_total_current": 0,
"i_a_current": 0,
"i_b_current": 0,
"i_c_current": 0,
"timeout": 1500000000
},
"busway": {
"last_communication_time": "0001-01-01T00:00:00Z",
"instant_power": 0,
"instant_reactive_power": 0,
"instant_apparent_power": 0,
"frequency": 0,
"energy_exported": 0,
"energy_imported": 0,
"instant_average_voltage": 0,
"instant_total_current": 0,
"i_a_current": 0,
"i_b_current": 0,
"i_c_current": 0
},
"frequency": {
"last_communication_time": "0001-01-01T00:00:00Z",
"instant_power": 0,
"instant_reactive_power": 0,
"instant_apparent_power": 0,
"frequency": 0,
"energy_exported": 0,
"energy_imported": 0,
"instant_average_voltage": 0,
"instant_total_current": 0,
"i_a_current": 0,
"i_b_current": 0,
"i_c_current": 0
},
"generator": {
"last_communication_time": "0001-01-01T00:00:00Z",
"instant_power": 0,
"instant_reactive_power": 0,
"instant_apparent_power": 0,
"frequency": 0,
"energy_exported": 0,
"energy_imported": 0,
"instant_average_voltage": 0,
"instant_total_current": 0,
"i_a_current": 0,
"i_b_current": 0,
"i_c_current": 0
}
}
 
  • Informative
Reactions: NinjaVece
/api/meters/aggregates includes those. Here's a sample:


{
"site": {
"last_communication_time": "2019-05-08T15:52:50.489021579-07:00",
"instant_power": -4728.14990234375,
"instant_reactive_power": 111.89999961853027,
"instant_apparent_power": 4729.473872318975,
"frequency": 60,
"energy_exported": 7109714.548918119,
"energy_imported": 10740907.429195896,
"instant_average_voltage": 125.875,
"instant_total_current": 0,
"i_a_current": 0,
"i_b_current": 0,
"i_c_current": 0,
"timeout": 1500000000
},
"battery": {
"last_communication_time": "2019-05-08T15:52:50.490166902-07:00",
"instant_power": 730,
"instant_reactive_power": 0,
"instant_apparent_power": 730,
"frequency": 60.013999999999996,
"energy_exported": 1666960,
"energy_imported": 2107550,
"instant_average_voltage": 251.65,
"instant_total_current": -17.700000000000003,
"i_a_current": 0,
"i_b_current": 0,
"i_c_current": 0,
"timeout": 1500000000
},
"load": {
"last_communication_time": "2019-05-08T15:52:50.489021579-07:00",
"instant_power": 730.4965934209245,
"instant_reactive_power": -36.4131006955253,
"instant_apparent_power": 731.4035732082787,
"frequency": 60,
"energy_exported": 0,
"energy_imported": 15146371.921944445,
"instant_average_voltage": 125.875,
"instant_total_current": 5.803349302251634,
"i_a_current": 0,
"i_b_current": 0,
"i_c_current": 0,
"timeout": 1500000000
},
"solar": {
"last_communication_time": "2019-05-08T15:52:50.489140912-07:00",
"instant_power": 4698.6201171875,
"instant_reactive_power": -147.17000579833984,
"instant_apparent_power": 4700.924378911637,
"frequency": 60,
"energy_exported": 11956234.147228653,
"energy_imported": 465.1055619854691,
"instant_average_voltage": 125.86499786376953,
"instant_total_current": 0,
"i_a_current": 0,
"i_b_current": 0,
"i_c_current": 0,
"timeout": 1500000000
},
"busway": {
"last_communication_time": "0001-01-01T00:00:00Z",
"instant_power": 0,
"instant_reactive_power": 0,
"instant_apparent_power": 0,
"frequency": 0,
"energy_exported": 0,
"energy_imported": 0,
"instant_average_voltage": 0,
"instant_total_current": 0,
"i_a_current": 0,
"i_b_current": 0,
"i_c_current": 0
},
"frequency": {
"last_communication_time": "0001-01-01T00:00:00Z",
"instant_power": 0,
"instant_reactive_power": 0,
"instant_apparent_power": 0,
"frequency": 0,
"energy_exported": 0,
"energy_imported": 0,
"instant_average_voltage": 0,
"instant_total_current": 0,
"i_a_current": 0,
"i_b_current": 0,
"i_c_current": 0
},
"generator": {
"last_communication_time": "0001-01-01T00:00:00Z",
"instant_power": 0,
"instant_reactive_power": 0,
"instant_apparent_power": 0,
"frequency": 0,
"energy_exported": 0,
"energy_imported": 0,
"instant_average_voltage": 0,
"instant_total_current": 0,
"i_a_current": 0,
"i_b_current": 0,
"i_c_current": 0
}
}

Yes, I see it now. I'm in touch with the guy developing Tesla for Windows (he's in Australia) and he has stated that the user API - that is, the one that can be accessed anywhere in the world through your login - doesn't have this information. He was wondering if the local LAN API might have it after I informed him of the 66 Hz issue and how it would be good if the software displayed the Hertz level, etc.

He doesn't have a PW2 of his own so can only test out his uncle's from afar (User API) and he is testing his Model 3 interface using a token from me. But I will be forwarding him this list of the local Gateway API that can be accessed directly from the LAN through Ethernet or WiFi and maybe he can whip something I can test for him.
 
Sadly, most of those /api/meters/aggregates values seem to be at best redundant. The "site" section, for example, represents the grid, but continues to report valid frequencies & voltages even when the grid is down (as far as I could tell in my testing last night, the only value that changed when I threw my main breaker was the /api/system_status/grid_status value and of course the site.*_power values, but everything else in site was unchanged). Similar for solar, though that one makes a bit more sense since there aren't dedicated voltage sensors for the solar path, and the inverter still has power even when it's not generating (still seems better to just not report it at all then to report made-up/assumed/duplicated values, and solar.instant_total_current reports 0 even though it does have a current sensor for that).

I started off collecting a bunch of those readings assuming they'd say something useful, but in hindsight it seems like I can throw most of the data away as it's rather useless.
 
Sadly, most of those /api/meters/aggregates values seem to be at best redundant. The "site" section, for example, represents the grid, but continues to report valid frequencies & voltages even when the grid is down (as far as I could tell in my testing last night, the only value that changed when I threw my main breaker was the /api/system_status/grid_status value and of course the site.*_power values, but everything else in site was unchanged). Similar for solar, though that one makes a bit more sense since there aren't dedicated voltage sensors for the solar path, and the inverter still has power even when it's not generating (still seems better to just not report it at all then to report made-up/assumed/duplicated values, and solar.instant_total_current reports 0 even though it does have a current sensor for that).

I started off collecting a bunch of those readings assuming they'd say something useful, but in hindsight it seems like I can throw most of the data away as it's rather useless.

Any information like that would be a boon for @dpskipper who develops Tesla for Windows. He's looking into improving the software to use the Gateway API if it is running in the same LAN as the PW2 is on. But insights from others is a big plus.
 
Perhaps @dpskipper could set up a VPN to his Uncle's network. That would allow him to do his own testing. The aggregates call doesn't require authentication, so it's easy to use if you have access to the Gateway over the LAN. I just had to work around the certificate validation and mangled CORS headers to get a simple monitoring page implemented.
 
Perhaps @dpskipper could set up a VPN to his Uncle's network. That would allow him to do his own testing. The aggregates call doesn't require authentication, so it's easy to use if you have access to the Gateway over the LAN. I just had to work around the certificate validation and mangled CORS headers to get a simple monitoring page implemented.

I'll have to ask him about getting a VPN setup. Its a question of how competent his network hardware is and if its possible to open up ports for a SSH proxy...
 
I'll have to ask him about getting a VPN setup. Its a question of how competent his network hardware is and if its possible to open up ports for a SSH proxy...

Depending on how many hoops you're willing to jump through, you could just give him a Raspberry Pi based VPN server. I haven't tried setting up one myself since my Asus router will run an OpenVPN server itself, but this project looks like it would work: PiVPN: Simplest setup of OpenVPN
 
It was really easy to set up, I put PiVPN on a RPi I had sitting around when I went on vacation over Christmas, worked great. First power outage as Tesla was installing my Powerwall the SD card corrupted itself and it stopped booting, so I lost my setup but it should be pretty easy to get it back.
 
Anybody experiencing where setting real_mode to self-consumption results in backup-reserve being reset to 0% (in app), and 5% in Wizard - summary, no matter what the backup_reserve_percent json value is being set to? I'm on 1.35.2 Gateway firmware.

It's also annoying I have to stop and run the Sitemaster between mode changes, as just setting the mode and committing doesn't mean the PowerWall will actually perform the new mode, even though its status IS registering as the new mode. For instance, I've set it self-consumption mode, and then programmatically change it to backup-mode in the evening. However, its behavior stays in self-consumption mode (continues to power the home) until I've restarted Sitemaster. Then its in Standby where I expected it to change to.

Not stopping Sitemaster is possible if just reusing the Oauth token that hasn't expired yet. Getting a new Oauth token automatically stops Sitemaster. I guess this is why the Wizard logs you out everytime you completed some configuration.
 
Last edited:
Anybody experiencing where setting real_mode to self-consumption results in backup-reserve being reset to 0% (in app), and 5% in Wizard - summary, no matter what the backup_reserve_percent json value is being set to? I'm on 1.35.2 Gateway firmware.

It's also annoying I have to stop and run the Sitemaster between mode changes, as just setting the mode and committing doesn't mean the PowerWall will actually perform the new mode, even though its status IS registering as the new mode. For instance, I've set it self-consumption mode, and then programmatically change it to backup-mode in the evening. However, its behavior stays in self-consumption mode (continues to power the home) until I've restarted Sitemaster. Then its in Standby where I expected it to change to.

Not stopping Sitemaster is possible if just reusing the Oauth token that hasn't expired yet. Getting a new Oauth token automatically stops Sitemaster. I guess this is why the Wizard logs you out everytime you completed some configuration.
Never mind my backup-reserve problem -- it was a typo in my json key when setting that value.

Rewrote my operation-change flow to duplicate what the Installer Wizard does (force-login, change op modes, commit), and now it this fake TBC works to my satisfaction. I'll have to see if changing reserve needs a sitemaster restart.
 
Anyone had trouble with the Powerwall2 backup gateway being unreachable from other devices?

(Context: I'm trying to get my Linux synology diskstation running the python version courtesy of Ekul135 - ekul135/Powerwall2PVOutput.)

The gateway works fine and if I log in on the TEG* network, it shows that it is connected to my home Wifi.
My ASUS router shows it as appearing on my home wifi no problem ... 192.168.2.11.

But if I ping it from my Mac or from my Linux Synology Diskstation, it says the device is unreachable.

Is this an installer setting? Some security setting on my router? Why wouldn't I be able to ping my Backup Gateway?

Thanks for any and all tips...I'm probably missing something basic.
 
Have you checked that the router doesn't have "network isolation" or something like that enabled? I'm hardwired rather than using Wifi, but I don't think that should make a difference. Does your ASUS router have a ping function? If you can ping it from the router but not other network nodes, that would indicate it's likely a router configuration issue.
 
Have you checked that the router doesn't have "network isolation" or something like that enabled? I'm hardwired rather than using Wifi, but I don't think that should make a difference. Does your ASUS router have a ping function? If you can ping it from the router but not other network nodes, that would indicate it's likely a router configuration issue.

Thanks @cwied ... I logged onto the Backup Gateway (BUG) network, rescanned and readded my home network, and then waited... Now it appears to be properly recognized by my mac laptop, sitting on my LAN wifi, and I can hit the APIs using Chrome on my Mac.

I'm trying to run the Python app on my Mac now, and we'll see what happens.

My Synology Diskstation (linux) appears to be properly on the same network, but cannot access the BUG yet...despite ifconfig showing it as being attached on the same network. (See below...and yes, my Synology has two network interfaces, one DHCP and one Static.)


While I debug that, and try getting just my Mac Python app talking properly, does anyone have tips on how to get the Tesla BUG to use a static IP on Wifi? I don't see any configuration for that, but perhaps it's somewhere in the API documentation?

Thanks all, for the help!!!

PS: Here's my synology ifconfig:

eth0 Link encap:Ethernet HWaddr 00:11:32:18:ED:FF

inet addr:192.168.2.185 Bcast:192.168.2.255 Mask:255.255.255.0

inet6 addr: fe80::211:32ff:fe18:edff/64 Scope:Link

UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

RX packets:10233826 errors:0 dropped:0 overruns:0 frame:0

TX packets:5698973 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:1000

RX bytes:10558597479 (9.8 GiB) TX bytes:2782726175 (2.5 GiB)

Interrupt:16 memory 0xc0400000-c0420000


eth1 Link encap:Ethernet HWaddr 00:11:32:18:EE:00

inet addr:192.168.2.2 Bcast:192.168.2.255 Mask:255.255.255.0

inet6 addr: fe80::211:32ff:fe18:ee00/64 Scope:Link

UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

RX packets:2306872 errors:0 dropped:0 overruns:0 frame:0

TX packets:1320032 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:1000

RX bytes:2245583842 (2.0 GiB) TX bytes:873381017 (832.9 MiB)

Interrupt:17 memory 0xc0300000-c0320000


lo Link encap:Local Loopback

inet addr:127.0.0.1 Mask:255.0.0.0

inet6 addr: ::1/128 Scope:Host

UP LOOPBACK RUNNING MTU:65536 Metric:1

RX packets:363869 errors:0 dropped:0 overruns:0 frame:0

TX packets:363869 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:0

RX bytes:39006061 (37.1 MiB) TX bytes:39006061 (37.1 MiB)
 
If you want the Gateway to have a static IP address, the easiest way is to configure the DHCP server on your router to hand it the same address each time. On my Asus router, this is under Advanced Settings->LAN->DHCP server, but I run a modified firmware so I'm not sure if this is a stock feature.
 
  • Helpful
Reactions: Story