{"id":16981310,"url":"https://github.com/jasonacox/pypowerwall","last_synced_at":"2026-04-19T03:11:49.026Z","repository":{"id":39715904,"uuid":"417909189","full_name":"jasonacox/pypowerwall","owner":"jasonacox","description":"Python API for Tesla Powerwall and Solar Power Data","archived":false,"fork":false,"pushed_at":"2026-04-12T03:31:28.000Z","size":4549,"stargazers_count":202,"open_issues_count":47,"forks_count":50,"subscribers_count":17,"default_branch":"main","last_synced_at":"2026-04-12T04:21:22.611Z","etag":null,"topics":["battery","dashboard","inverter-graphs","powerwall","powerwall-api","powerwall-status","powerwall-temps","python","solar","solar-panel-data","solar-strings","tesla","tesla-api","tesla-powerwall","vitals"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jasonacox.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-10-16T18:08:02.000Z","updated_at":"2026-04-12T03:31:31.000Z","dependencies_parsed_at":"2026-02-22T10:02:24.516Z","dependency_job_id":null,"html_url":"https://github.com/jasonacox/pypowerwall","commit_stats":{"total_commits":499,"total_committers":18,"mean_commits":27.72222222222222,"dds":"0.18436873747494986","last_synced_commit":"267d6c0814c965bd1ce5f28a261b7d53f79c2670"},"previous_names":[],"tags_count":81,"template":false,"template_full_name":null,"purl":"pkg:github/jasonacox/pypowerwall","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jasonacox%2Fpypowerwall","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jasonacox%2Fpypowerwall/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jasonacox%2Fpypowerwall/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jasonacox%2Fpypowerwall/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jasonacox","download_url":"https://codeload.github.com/jasonacox/pypowerwall/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jasonacox%2Fpypowerwall/sbom","scorecard":{"id":507211,"data":{"date":"2025-08-11","repo":{"name":"github.com/jasonacox/pypowerwall","commit":"d94bcec742ee1fa723a7f5b3137c8d44971c1330"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.1,"checks":[{"name":"Maintained","score":10,"reason":"30 commit(s) and 11 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":0,"reason":"Found 1/16 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: topLevel 'contents' permission set to 'read': .github/workflows/jekyll-gh-pages.yml:14","Warn: no topLevel permission defined: .github/workflows/pwsim-docker.yml:1","Warn: no topLevel permission defined: .github/workflows/pylint.yml:1","Warn: no topLevel permission defined: .github/workflows/simtest.yml:1","Warn: no topLevel permission defined: .github/workflows/test.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":3,"reason":"7 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-8gq9-2x98-w8hf","Warn: Project is vulnerable to: GHSA-8qvm-5x2c-j2w7","Warn: Project is vulnerable to: PYSEC-2014-14 / GHSA-652x-xj99-gmcc","Warn: Project is vulnerable to: GHSA-9hjg-9r4m-mvj7","Warn: Project is vulnerable to: GHSA-9wx4-h78v-vm56","Warn: Project is vulnerable to: PYSEC-2014-13 / GHSA-cfj3-7x9c-4p3h","Warn: Project is vulnerable to: PYSEC-2018-28 / GHSA-x84v-xcm2-53pg"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/pwsim-docker.yml:10"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/jekyll-gh-pages.yml:30: update your workflow using https://app.stepsecurity.io/secureworkflow/jasonacox/pypowerwall/jekyll-gh-pages.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/jekyll-gh-pages.yml:32: update your workflow using https://app.stepsecurity.io/secureworkflow/jasonacox/pypowerwall/jekyll-gh-pages.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/jekyll-gh-pages.yml:34: update your workflow using https://app.stepsecurity.io/secureworkflow/jasonacox/pypowerwall/jekyll-gh-pages.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/jekyll-gh-pages.yml:39: update your workflow using https://app.stepsecurity.io/secureworkflow/jasonacox/pypowerwall/jekyll-gh-pages.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/jekyll-gh-pages.yml:51: update your workflow using https://app.stepsecurity.io/secureworkflow/jasonacox/pypowerwall/jekyll-gh-pages.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pwsim-docker.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/jasonacox/pypowerwall/pwsim-docker.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/pwsim-docker.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/jasonacox/pypowerwall/pwsim-docker.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/pwsim-docker.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/jasonacox/pypowerwall/pwsim-docker.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/pwsim-docker.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/jasonacox/pypowerwall/pwsim-docker.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/pwsim-docker.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/jasonacox/pypowerwall/pwsim-docker.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pylint.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/jasonacox/pypowerwall/pylint.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pylint.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/jasonacox/pypowerwall/pylint.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/simtest.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/jasonacox/pypowerwall/simtest.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/simtest.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/jasonacox/pypowerwall/simtest.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/jasonacox/pypowerwall/test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/jasonacox/pypowerwall/test.yml/main?enable=pin","Warn: containerImage not pinned by hash: proxy/Dockerfile:1: pin your Docker image by updating python:3.10-alpine to python:3.10-alpine@sha256:24cab748bf7bd8e3d2f9bb4e5771f17b628417527a4e1f2c59c370c2a8a27f1c","Warn: containerImage not pinned by hash: proxy/Dockerfile.beta:1: pin your Docker image by updating python:3.10-alpine to python:3.10-alpine@sha256:24cab748bf7bd8e3d2f9bb4e5771f17b628417527a4e1f2c59c370c2a8a27f1c","Warn: containerImage not pinned by hash: pwsimulator/Dockerfile:1: pin your Docker image by updating python:3.7-alpine to python:3.7-alpine@sha256:f3d31c8677d03f0b3c724446077f229a6ce9d3ac430f5c08cd7dff00292048c3","Warn: pipCommand not pinned by hash: proxy/Dockerfile:9","Warn: pipCommand not pinned by hash: proxy/Dockerfile.beta:9","Warn: pipCommand not pinned by hash: pwsimulator/Dockerfile:3","Warn: pipCommand not pinned by hash: .github/workflows/pylint.yml:19","Warn: pipCommand not pinned by hash: .github/workflows/pylint.yml:20","Warn: pipCommand not pinned by hash: .github/workflows/pylint.yml:21","Warn: pipCommand not pinned by hash: .github/workflows/simtest.yml:35","Warn: pipCommand not pinned by hash: .github/workflows/simtest.yml:36","Warn: pipCommand not pinned by hash: .github/workflows/simtest.yml:37","Warn: pipCommand not pinned by hash: .github/workflows/test.yml:29","Warn: pipCommand not pinned by hash: .github/workflows/test.yml:30","Warn: pipCommand not pinned by hash: .github/workflows/test.yml:31","Info:   0 out of  12 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   4 third-party GitHubAction dependencies pinned","Info:   0 out of  12 pipCommand dependencies pinned","Info:   0 out of   3 containerImage dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 21 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-19T23:31:47.374Z","repository_id":39715904,"created_at":"2025-08-19T23:31:47.375Z","updated_at":"2025-08-19T23:31:47.375Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31992902,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T20:23:30.271Z","status":"online","status_checked_at":"2026-04-19T02:00:07.110Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["battery","dashboard","inverter-graphs","powerwall","powerwall-api","powerwall-status","powerwall-temps","python","solar","solar-panel-data","solar-strings","tesla","tesla-api","tesla-powerwall","vitals"],"created_at":"2024-10-14T02:05:06.518Z","updated_at":"2026-04-19T03:11:49.012Z","avatar_url":"https://github.com/jasonacox.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pyPowerwall\n\n[![License](https://img.shields.io/github/license/jasonacox/pypowerwall)](https://img.shields.io/github/license/jasonacox/pypowerwall)\n[![PyPI version](https://badge.fury.io/py/pypowerwall.svg)](https://badge.fury.io/py/pypowerwall)\n[![CI](https://github.com/jasonacox/pypowerwall/actions/workflows/test.yml/badge.svg)](https://github.com/jasonacox/pypowerwall/actions/workflows/test.yml)\n[![simtest](https://github.com/jasonacox/pypowerwall/actions/workflows/simtest.yml/badge.svg)](https://github.com/jasonacox/pypowerwall/actions/workflows/simtest.yml)\n[![Python Version](https://img.shields.io/pypi/pyversions/pypowerwall)](https://img.shields.io/pypi/pyversions/pypowerwall)\n[![PyPI Downloads](https://static.pepy.tech/badge/pypowerwall/month)](https://static.pepy.tech/badge/pypowerwall/month)\n\npyPowerwall is a Python module to interface with Tesla Energy Gateways for Powerwall and solar power data. It supports local access to Powerwall, Powerwall 2, Powerwall+ and Powerwall 3 systems. It also provides Tesla Owner and FleetAPI cloud access for all systems including Solar-only systems. For Powerwall 3 on wired LAN, the v1r TEDAPI mode provides full local access using RSA-signed protobuf messages without needing Wi-Fi access.\n\n\u003e ⚠️ **NOTICE:** As of Powerwall Firmware version 25.10.0, network routing to the TEDAPI endpoint (`192.168.91.1`) is no longer supported by Tesla. You must connect directly to the Powerwall's Wi‑Fi access point to access TEDAPI data.\n\n## Description\n\nThis Python module can be used to monitor and control Tesla Energy Powerwalls. It uses a single class (`Powerwall`) and simple functions to fetch energy data and poll API endpoints on the Gateway.  \n\npyPowerwall will cache the authentication headers and API call responses to help reduce the number of calls made to the Gateway (useful if you are polling the Powerwall frequently for trending data).\n\n* Works with Tesla Energy Gateways - Powerwall, Powerwall+ and Powerwall 3\n* Access provided via Local Gateway APIs, Tesla FleetAPI (official), Tesla Owners API (unofficial), and v1r LAN TEDAPI (Powerwall 3).\n* Will cache authentication to reduce load on Powerwall Gateway\n* Will cache responses to limit the number of calls to the Powerwall Gateway or cloud (optional/user‑definable)\n* Will re-use HTTP connections to the Powerwall Gateway for reduced load and faster response times\n* Provides solar string data for Powerwall+ and Powerwall 3 systems.\n\n## Setup\n\nYou can clone this repo or install the package with pip.  Once installed, pyPowerwall can scan your local network to find the IP address of your Tesla Powerwall Gateway.\n\n```bash\n# Install pyPowerwall\npython3 -m pip install pypowerwall\n\n# Option 1 - LOCAL MODE - Scan Network for Powerwalls\npython3 -m pypowerwall scan\n\n# Option 2 - FLEETAPI CLOUD MODE - Setup to use the official Tesla FleetAPI - See notes below.\npython3 -m pypowerwall fleetapi\n\n# Option 3 - CLOUD MODE - Setup to use Tesla Owners cloud API\npython3 -m pypowerwall setup\n\n# Option 4 - TEDAPI MODE - Test this mode (requires extended setup - see below)\npython3 -m pypowerwall tedapi\n\n# Option 5 - v1r LAN TEDAPI MODE - Powerwall 3 wired LAN access (see below)\n```\n\n### Local Setup - Option 1\n\nThe Tesla Powerwall, Powerwall 2 and Powerwall+ have a local LAN based Web Portal and API that you can use to monitor your Powerwall. It requires that you (or your installer) have the IP address (see scan above) and set up *Customer Login* credentials on your Powerwall Gateway. That is all that is needed to connect. \n\nThe Powerwall 3 does not have a traditional Web Portal or API but you can access it via the cloud (see options 2 and 3), via the TEDAPI Wi-Fi access point (option 4), or via the wired LAN using v1r TEDAPI (option 5).\n\nLocally accessible extended device vitals metrics are available using the TEDAPI method (see options 4 and 5 below).\n\n### FleetAPI Cloud Setup - Option 2\n\nFleetAPI is the official Tesla API for accessing your Tesla products. This setup has some additional setup requirements that you will be prompted to do:\n\nStep 1 - Tesla Partner Account - Sign in to Tesla Developer Portal and make an App Access Request: See [Tesla App Access Request](https://developer.tesla.com/request) - During this process, you will need to set up and remember the following account settings: \n\n   * CLIENT_ID - This will be provided to you by Tesla when your request is approved.\n   * CLIENT_SECRET - Same as above.\n   * DOMAIN - The domain name of a website you own and control.\n   * REDIRECT_URI - This is the URL that Tesla will direct you to after you authenticate. This landing URL (on your website) will extract the GET variable `code`, which is a one-time use authorization code needed during the pyPowerwall setup. You can use https://pypowerwall.com/code or copy the code from [index.html](./tools/fleetapi/index.html) to your site and update REDIRECT_URI with that URL. Alternatively, you can just copy the URL from the 404 page during the authorization process (the code is in the URL).\n\nStep 2 - Run the [create_pem_key.py](./tools/fleetapi/create_pem_key.py) script and place the **public** key on your website at the URL: https://{DOMAIN}/.well-known/appspecific/com.tesla.3p.public-key.pem\n\nStep 3 - Run `python3 -m pypowerwall fleetapi` - The credentials and tokens will be stored in the `.pypowerwall.fleetapi` file.\n\n### Cloud Mode - Option 3\n\nThe unofficial Tesla Owners API allows FleetAPI access (option 2) without having to set up a website and PEM key. Follow the directions given to you by running `python3 -m pypowerwall setup`. The credentials and site_id will be stored in `.pypowerwall.auth` and `.pypowerwall.site`.\n\n### TEDAPI Mode - Option 4\n\nWith version v0.10.0+, pypowerwall can access the TEDAPI endpoint on the Gateway over **Wi-Fi**. This API offers additional metrics related to string data, voltages, and alerts. You will need the Gateway Wi‑Fi password (found on the QR sticker on the Powerwall Gateway) and network access to `192.168.91.1` (either via the Gateway’s Wi‑Fi AP or a static route from your LAN).\n\n#### Full vs Hybrid TEDAPI\n\nOption 4 operates in two sub-modes depending on which credentials you provide:\n\n* **Full TEDAPI** — Set only `gw_pwd` (leave `password` empty). Uses the full Gateway Wi‑Fi password for HTTP Basic Auth directly to the TEDAPI protobuf endpoint. Works on PW2/+/3.\n* **Hybrid TEDAPI** — Set both `password` (last 5 chars) and `gw_pwd`. The customer password authenticates via `/api/login/Basic` for standard JSON API access, while `gw_pwd` enables TEDAPI for supplemental vitals data (string voltages, per‑device alerts, etc.). Useful on PW2/+ where the customer API provides data that TEDAPI does not.\n\n#### Network Requirements (Wi-Fi)\n\nYour machine must be able to reach `192.168.91.1`. Options:\n* Connect directly to the Gateway’s Wi‑Fi access point\n* Add a static route from your LAN through the Gateway’s home-network IP (see examples below)\n\n\u003e **Note:** Some firmware versions (25.10.0+) may block routed access to 192.168.91.1. In that case, connect directly to the Gateway Wi‑Fi.\n\n\u003e ⚠️ **TEDAPI Limitations:** Some functions are only available via FleetAPI or Cloud mode. Known limitations include `get_grid_charging()` and `get_grid_export()`, which rely on Fleet API endpoints not exposed locally — these return `None` in TEDAPI mode with a log warning. Use FleetAPI (Option 2) or Cloud mode (Option 3) for full functionality.\n\nIn the examples below, change **192.168.0.100** to the IP address of the Powerwall Gateway (or Inverter) on your LAN. Also, the **onlink** parameter may be necessary for Linux.\n\n#### Linux Ubuntu and RPi\n```bash\n# Can add to /etc/rc.local for persistence\nsudo ip route add 192.168.91.1 via 192.168.0.100 [onlink]\n```\n\nSee `examples/network_route.py` for two different approaches to do this programmatically in Python.\n\n#### macOS\n```\nsudo route add -host 192.168.91.1 192.168.0.100 # Temporary \nnetworksetup -setadditionalroutes Wi-Fi 192.168.91.1 255.255.255.255 192.168.0.100 # Persistent\n```\n\n#### Windows - Using the persistence flag - Administrator Shell\n```\nroute -p add 192.168.91.1 mask 255.255.255.255 192.168.0.100\n```\n\n#### Windows Subsystem for Linux (WSL 2–specific)\nFollow the instructions for Linux, but you must edit (from the host Windows OS) `%USERPROFILE%\\.wslconfig` and add the following settings:\n```\n[wsl2]\nnetworkingMode=mirrored\n```\n\n```bash\n# Test\npython3 -m pypowerwall tedapi\n```\n\n#### TEDAPI Troubleshooting\n\n- Connection refused/timeout: Ensure you’re connected to the Powerwall’s Wi‑Fi or have a working route to 192.168.91.1. Some firmware versions (25.10.0+) block routing; connect directly to the PW Wi‑Fi.\n- Auth failures: Use the Gateway Wi‑Fi password from the QR label as `gw_pwd` (case‑sensitive). Customer portal passwords do not work for TEDAPI.\n- TLS/certificate warnings: TEDAPI uses a self‑signed cert; most tools need `--insecure` (curl) or `verify=False` (requests). Use only on trusted networks.\n- Hybrid mode quirks (PW2/+): If both customer `password`/`email` and `gw_pwd` are provided, TEDAPI data augments local APIs; try removing customer creds if you only need TEDAPI.\n- QNAP/Appliance routing: Static routes from shell may be ignored; use the appliance’s network control panel to add a persistent host route.\n\n### v1r LAN TEDapi Setup - Option 5 (Powerwall 3 Wired LAN)\n\nThe Powerwall 3 exposes endpoints on the **wired LAN** (the vendor/third-party Ethernet port) that provide local access to Powerwall data without needing Wi-Fi access to `192.168.91.1`. This is especially useful for always-on monitoring setups where a wired Ethernet connection to the Powerwall gateway is available.\n\nOption 5 has two sub-modes:\n\n* **Basic LAN** — Uses `/api/login/Basic` for a Bearer token + standard JSON API endpoints. No FleetAPI setup or RSA keys needed. Provides core power/battery/grid data (3 endpoints).\n* **Full v1r** — Uses RSA-4096 signed protobuf messages to the `/tedapi/v1r` endpoint. Requires one-time FleetAPI key registration. Provides full data access (config, firmware, vitals, strings, components) equivalent to Wi-Fi TEDAPI.\n\n#### Network Requirements (Wired LAN)\n\nThe Powerwall 3 gateway has a wired Ethernet port on the TEG (Tesla Energy Gateway) unit that operates on an internal vendor subnet — typically `10.42.1.0/24` or `10.45.1.0/24`. This is **not** your home LAN IP.\n\nTo reach this subnet you need a Layer 2 connection to the TEG Ethernet port:\n* **SPAN panel** — Provides this natively; the SPAN connects to the TEG Ethernet and bridges it to your home network\n* **Network bridge** — A Linux bridge (e.g., `br-tap`) joining the TEG Ethernet interface to your LAN\n* **Direct cable** — Ethernet cable from your machine to the TEG port (you will need a static IP on the 10.42.1.x subnet)\n* **VLAN** — Managed switch with a VLAN that includes the TEG port\n\n\u003e **Important:** The v1r/Basic LAN endpoints listen only on the vendor subnet (10.42.1.x). Requests to the Powerwall’s home LAN IP will not reach these endpoints. Use `ping 10.42.1.x` to verify connectivity before configuration.\n\n#### Basic LAN Access (No RSA Key Required)\n\nIf you only need core power, battery, and grid data over the wired LAN, you can use the standard local mode without RSA key registration. This uses the same `/api/login/Basic` endpoint that the Tesla app uses:\n\n```python\nimport pypowerwall\n\npw = pypowerwall.Powerwall(\n    host=\"10.42.1.40\",                # Powerwall wired LAN IP (vendor subnet)\n    password=\"XXXXX\",                 # Customer password (last 5 of GW password)\n    email=\"user@example.com\",\n    timezone=\"America/Los_Angeles\"\n)\n\n# Basic power data available without RSA:\nprint(pw.power())       # {site, solar, battery, load} in watts\nprint(pw.level())       # Battery percentage\nprint(pw.grid_status()) # Grid connection status\n```\n\nThis gives you the three core endpoints: `/api/meters/aggregates`, `/api/system_status/soe`, and `/api/system_status/grid_status`. Most other `/api/*` endpoints return 404 on the wired LAN. For full access to vitals, strings, firmware, components, and device-level data, use Full v1r mode below.\n\n##### Getting a Bearer Token (curl / shell)\n\nYou can also access these endpoints directly without pypowerwall using a Bearer token:\n\n```bash\n# Get a Bearer token using the customer password (last 5 chars of GW password)\nTOKEN=$(curl -sk -X POST https://10.0.1.50/api/login/Basic \\\n  -H ‘Content-Type: application/json’ \\\n  -d ‘{\"username\":\"customer\",\"password\":\"XXXXX\",\"email\":\"user@example.com\",\"force_sm_off\":false}’ \\\n  | python3 -c \"import sys,json; print(json.load(sys.stdin)[‘token’])\")\n\n# Power data (solar, battery, grid, load)\ncurl -sk -H \"Authorization: Bearer $TOKEN\" https://10.0.1.50/api/meters/aggregates\n\n# Battery level (state of energy)\ncurl -sk -H \"Authorization: Bearer $TOKEN\" https://10.0.1.50/api/system_status/soe\n\n# Grid connection status\ncurl -sk -H \"Authorization: Bearer $TOKEN\" https://10.0.1.50/api/system_status/grid_status\n```\n\n**Note:** The token is also returned in the response cookies (`AuthCookie` and `UserRecord`).\n\n#### Full v1r LAN Access (RSA Key Required)\n\nWith an RSA key registered via `v1r_register.py`, you get full TEDapi access over the wired LAN — equivalent to what was previously only available over Wi-Fi:\n\n\u003e **Note:** The easiest way to register is using the Tesla Owner API (no developer app required) — just sign in with your Tesla account. Run `python -m pypowerwall register` and select option 1. If you already have FleetAPI set up (Option 2), you can also use those credentials by selecting option 2.\n\n##### Requirements\n\n1. **Wired LAN connection** to the Powerwall 3 gateway vendor subnet (see Network Requirements above)\n2. **RSA-4096 key pair** registered with the Powerwall via Tesla Owner API or Fleet API\n3. **Gateway password** (`gw_pwd` — from the QR sticker on the gateway; the last 5 characters are auto-derived for login)\n\n##### RSA Key Registration\n\nUse `v1r_register.py` (or `python -m pypowerwall register` after pip install) to generate and register an RSA-4096 key pair with the Powerwall:\n\n```bash\npython3 v1r_register.py\n```\n\nWhen prompted, select the registration method:\n- **Option 1 — Tesla Owner API** (recommended): Just sign in with your Tesla account. No developer app needed.\n- **Option 2 — Tesla Fleet API**: Requires a registered developer application (CLIENT_ID, CLIENT_SECRET, REDIRECT_URI).\n\nThe script will then:\n1. Generate an RSA-4096 key pair (saves private key to `tedapi_rsa_private.pem`)\n2. Walk you through Tesla OAuth to authorize the registration\n3. Register the public key with the Powerwall\n4. Prompt you to confirm registration by toggling a Powerwall breaker off and back on (if not auto-verified)\n\nAfter the breaker toggle, wait for the Powerwall status light to turn from red back to white — this can take 30-60 seconds. The script will poll for confirmation and show whether the key was authorized.\n\n**Note (Fleet API only):** Tesla Fleet API requires your application’s public key to be served at `https://{DOMAIN}/.well-known/appspecific/com.tesla.3p.public-key.pem`. A Cloudflare Worker or any static web host can serve this file.\n\n##### Full v1r Python Example\n\n```python\nimport pypowerwall\n\npw = pypowerwall.Powerwall(\n    host=\"10.42.1.40\",                         # Powerwall wired LAN IP (vendor subnet)\n    gw_pwd=\"ABCDEXXXXX\",                       # Full gateway password (last 5 auto-derived)\n    email=\"user@example.com\",\n    timezone=\"America/Los_Angeles\",\n    rsa_key_path=\"/path/to/tedapi_rsa_private.pem\"  # RSA key from v1r_register.py\n)\n\n# All standard methods work over v1r:\nprint(pw.level())       # Battery percentage\nprint(pw.power())       # {site, solar, battery, load} in watts\nprint(pw.solar())       # Solar power in watts\nprint(pw.battery())     # Battery power in watts\nprint(pw.grid())        # Grid power in watts\nprint(pw.load())        # Load power in watts\nprint(pw.version())     # Firmware version\nprint(pw.vitals())      # Per-device vitals (PVAC, PVS, TEPOD, PINV, etc.)\nprint(pw.strings())     # Solar string data\nprint(pw.alerts())      # Active device alerts\n\n# API polling:\npw.poll(‘/api/meters/aggregates’)              # Detailed meter data\npw.poll(‘/api/system_status/soe’)              # Battery state of energy\npw.poll(‘/api/system_status/grid_status’)      # Grid connection status\npw.poll(‘/api/system_status’)                  # Full system status\npw.poll(‘/api/site_info’)                      # Site configuration\npw.poll(‘/api/operation’)                      # Operation mode\n```\n\n#### v1r Docker Proxy Setup\n\nFor always-on monitoring (e.g., with [Powerwall-Dashboard](https://github.com/jasonacox/Powerwall-Dashboard)), configure the proxy container with these environment variables:\n\n```env\nPW_HOST=10.42.1.40                  # Powerwall wired LAN IP (vendor subnet)\nPW_GW_PWD=ABCDEXXXXX                # Full gateway password (last 5 auto-derived for login)\nPW_TIMEZONE=America/Los_Angeles\nPW_RSA_KEY_PATH=/app/.auth/tedapi_rsa_private.pem\n```\n\nMount the RSA private key into the container at the path specified by `PW_RSA_KEY_PATH`.\n\n\u003e **Tip:** You no longer need to set both `PW_PASSWORD` and `PW_GW_PWD`. Just set `PW_GW_PWD` with the full gateway password — the last 5 characters are automatically used for `/api/login/Basic` authentication. Setting `PW_PASSWORD` explicitly still works for backward compatibility.\n\n#### Password Configuration\n\npyPowerwall accepts the gateway password via `PW_GW_PWD` (the full password from the QR sticker). When v1r mode needs the 5-character customer password for `/api/login/Basic`, it is automatically derived from the last 5 characters of `PW_GW_PWD`. You can still set `PW_PASSWORD` explicitly for backward compatibility.\n\n| Mode | `PW_GW_PWD` | `PW_PASSWORD` | `PW_RSA_KEY_PATH` | `PW_HOST` |\n|------|:-----------:|:-------------:|:------------------:|:---------:|\n| Option 4 full (WiFi) | required | — | — | 192.168.91.1 |\n| Option 4 hybrid (WiFi) | required | required | — | 192.168.91.1 |\n| Option 5 basic (LAN) | — | required | — | vendor subnet IP |\n| Option 5 v1r (LAN) | required | auto-derived | required | vendor subnet IP |\n| Option 1 local API | — | required | — | any |\n\n#### v1r Feature Parity\n\n| Feature | WiFi TEDapi (mode 4) | v1r LAN (mode 5) |\n|---------|:--------------------:|:-----------------:|\n| Config (site info, batteries) | Yes | Yes |\n| Firmware version | Yes | Yes |\n| Power (solar/battery/grid/load) | Yes | Yes |\n| Battery level (%) | Yes | Yes |\n| Grid status | Yes | Yes |\n| Site info \u0026 operation mode | Yes | Yes |\n| Per-device vitals (PVAC/PINV/POD) | Yes | Yes |\n| Component queries (PCH/BMS/HVP) | Yes | Yes |\n| Solar string data | Yes | Yes |\n| Multi-PW follower queries | Yes | Yes |\n| LAN control (reserve/mode/grid) | No | Yes |\n\n#### v1r WiFi Fallback\n\nWhen both the wired LAN (v1r) and WiFi TEDAPI connections are available, pyPowerwall transparently uses WiFi as a fallback transport for follower queries. This is automatically enabled when `PW_GW_PWD` is set alongside the v1r configuration. The proxy `/health` endpoint reports the active transports (e.g., `v1r_lan + wifi_tedapi`), and the mode string dynamically reflects what's active (e.g., `Local (v1r+wifi+control)`).\n\n#### LAN Control (v1r)\n\nIn v1r mode, pyPowerwall can control the Powerwall directly over the wired LAN without requiring cloud access. Control commands are sent as config updates via the v1r filestore `updateFileRequest` mechanism (read-modify-write with optimistic locking).\n\nSupported control operations:\n\n| Control | Method | Values |\n|---------|--------|--------|\n| Backup reserve | `set_reserve(level)` | 0-100 (percentage) |\n| Operation mode | `set_mode(mode)` | `self_consumption`, `backup` |\n| Grid charging | `set_grid_charging(enable)` | `True` / `False` |\n| Grid export | `set_grid_export(mode)` | `battery_ok`, `pv_only`, `never` |\n\n```python\nimport pypowerwall\n\npw = pypowerwall.Powerwall(\n    host=\"10.42.1.40\",\n    gw_pwd=\"ABCDEXXXXX\",\n    rsa_key_path=\"/path/to/tedapi_rsa_private.pem\"\n)\n\n# Read current settings\nprint(pw.get_mode())            # \"self_consumption\"\nprint(pw.get_reserve())         # 20\nprint(pw.get_grid_charging())   # False\nprint(pw.get_grid_export())     # \"pv_only\"\n\n# Set new values\npw.set_reserve(30)\npw.set_mode(\"backup\")\npw.set_grid_charging(True)\npw.set_grid_export(\"battery_ok\")\n\n# Max backup (v1r only) - sets reserve to 100% for duration\npw.schedule_max_backup(3600)        # 1 hour\npw.cancel_max_backup()\nprint(pw.get_backup_events())       # {\"manual_backup\": {...}, \"backup_events\": [...]}\n```\n\nFor proxy usage, set `PW_CONTROL_SECRET` and use the `/control/*` endpoints — no cloud setup needed when using v1r mode:\n\n```env\nPW_HOST=10.42.1.40\nPW_GW_PWD=ABCDEXXXXX\nPW_RSA_KEY_PATH=/app/.auth/tedapi_rsa_private.pem\nPW_CONTROL_SECRET=YourSecretToken\n```\n\n```bash\n# Read settings\ncurl http://localhost:8675/control/mode\ncurl http://localhost:8675/control/reserve\ncurl http://localhost:8675/control/grid_charging\ncurl http://localhost:8675/control/grid_export\ncurl http://localhost:8675/control/max_backup\n\n# Set values\ncurl -X POST -d \"value=backup\u0026token=$PW_CONTROL_SECRET\" http://localhost:8675/control/mode\ncurl -X POST -d \"value=30\u0026token=$PW_CONTROL_SECRET\" http://localhost:8675/control/reserve\ncurl -X POST -d \"value=true\u0026token=$PW_CONTROL_SECRET\" http://localhost:8675/control/grid_charging\ncurl -X POST -d \"value=pv_only\u0026token=$PW_CONTROL_SECRET\" http://localhost:8675/control/grid_export\ncurl -X POST -d \"value=3600\u0026token=$PW_CONTROL_SECRET\" http://localhost:8675/control/max_backup\ncurl -X POST -d \"value=cancel\u0026token=$PW_CONTROL_SECRET\" http://localhost:8675/control/max_backup\n```\n\n\u003e **Note:** LAN control requires v1r mode (RSA key registered). Basic LAN mode (no RSA key) does not support control operations. WiFi TEDAPI (mode 4) does not support LAN control — use FleetAPI cloud control instead.\n\n### FreeBSD Install\n\nFreeBSD users can install from ports or pkg [FreshPorts](https://www.freshports.org/net-mgmt/py-pypowerwall):\n\nVia pkg:\n```bash\n# pkg install net-mgmt/py-pypowerwall\n```\n\nVia ports:\n```bash\n# cd /usr/ports/net-mgmt/py-pypowerwall/ \u0026\u0026 make install clean\n```\n\nNote: pyPowerwall installation will attempt to install these required Python packages: _requests_, _protobuf_ and _teslapy_.\n\n## Programming with pyPowerwall\n\nAfter importing pypowerwall, you simply create a handle for your Powerwall device \nand call functions to poll data. A simple example is below or see [example.py](example.py) for an extended version:\n\n```python\nimport pypowerwall\n\n# Optional: Turn on Debug Mode\n# pypowerwall.set_debug(True)\n\n# Select option you wish to use.\nOPTION = 5\n\n# Connect to Powerwall based on selected option\nif OPTION == 1:\n   # Option 1 - LOCAL MODE - Customer Login (Powerwall 2 and Powerwall+ only)\n   password=\"password\"\n   email=\"email@example.com\"\n   host = \"10.0.1.123\"               # Address of your Powerwall Gateway\n   timezone = \"America/Los_Angeles\"  # Your local timezone\n   gw_pwd = None\n   rsa_key_path = None\n\nif OPTION == 2:\n   # Option 2 - FLEETAPI MODE - Requires Setup (Powerwall \u0026 Solar-Only)\n   host = password = email = \"\"\n   timezone = \"America/Los_Angeles\"\n   gw_pwd = None\n   rsa_key_path = None\n\nif OPTION == 3:\n   # Option 3 - CLOUD MODE - Requires Setup (Powerwall \u0026 Solar-Only)\n   host = password = \"\"\n   email='email@example.com'\n   timezone = \"America/Los_Angeles\"\n   gw_pwd = None\n   rsa_key_path = None\n\nif OPTION == 4:\n   # Option 4 - TEDAPI MODE - Requires access to Gateway (Powerwall 2, Powerwall+, and Powerwall 3)\n   host = \"192.168.91.1\"\n   gw_pwd = \"ABCDEFGHIJ\"\n   password = email = \"\"\n   timezone = \"America/Los_Angeles\"\n   rsa_key_path = None\n   # Uncomment the following for hybrid mode (Powerwall 2 and +)\n   #password=\"password\"\n   #email=\"email@example.com\"\n\nif OPTION == 5:\n   # Option 5 - v1r LAN TEDAPI MODE - Powerwall 3 wired LAN (requires RSA key registration)\n   host = \"10.0.1.50\"                  # Powerwall wired LAN IP (vendor subnet)\n   gw_pwd = \"ABCDEXXXXX\"              # Full gateway password from QR sticker (last 5 auto-derived)\n   password = \"\"                       # Not needed — auto-derived from gw_pwd\n   email = \"\"\n   timezone = \"America/Los_Angeles\"\nrsa_key_path = \"/path/to/tedapi_rsa_private.pem\"  # From v1r_register.py\n\n# Note on gw_pwd (Gateway Password)\n# - `gw_pwd` is the full Gateway Wi‑Fi password printed on the QR label.\n# - Used directly for TEDAPI HTTP Basic Auth in mode 4 (WiFi).\n# - In v1r mode (mode 5), the last 5 characters are auto-derived for /api/login/Basic.\n# - You only need to set `gw_pwd` — setting `password` separately is optional (backward compatible).\n# - If you set `gw_pwd` and leave `password` empty, pyPowerwall will:\n#     - Auto-enable full TEDAPI mode (mode 4) if no `rsa_key_path` is set.\n#     - Auto-enable v1r mode (mode 5) if `rsa_key_path` is set (derives last 5 chars).\n# - On Powerwall 2/+ you can set both `password`/`email` and `gw_pwd` for hybrid mode\n#   that combines customer APIs with TEDAPI for supplemental vitals data.\n#\n# Note on rsa_key_path (v1r LAN TEDapi)\n# - Only needed for Powerwall 3 wired LAN access (mode 5) with full protobuf data.\n# - Requires RSA-4096 key pair registered via Tesla Owner API or Fleet API (see v1r_register.py).\n# - Without rsa_key_path, basic LAN mode still works for core power/battery/grid data.\n\n# Connect to Powerwall - auto_select mode (local, fleetapi, cloud, tedapi, v1r)\npw = pypowerwall.Powerwall(host, password, email, timezone, gw_pwd=gw_pwd,\n                           rsa_key_path=rsa_key_path, auto_select=True)\n\n# Some System Info\nprint(\"Site Name: %s - Firmware: %s - DIN: %s\" % (pw.site_name(), pw.version(), pw.din()))\nprint(\"System Uptime: %s\\n\" % pw.uptime())\n\n# Pull Sensor Power Data\ngrid = pw.grid()\nsolar = pw.solar()\nbattery = pw.battery()\nhome = pw.home()\n\n# Display Data\nprint(\"Battery power level: %0.0f%%\" % pw.level())  # Actual level including 5% Tesla reserve\nprint(\"Tesla app level: %0.0f%%\" % pw.level(scale=True))  # Level as shown in Tesla App\nprint(\"Combined power metrics: %r\" % pw.power())\nprint(\"\")\n\n# Display Power in kW\nprint(\"Grid Power: %0.2fkW\" % (float(grid)/1000.0))\nprint(\"Solar Power: %0.2fkW\" % (float(solar)/1000.0))\nprint(\"Battery Power: %0.2fkW\" % (float(battery)/1000.0))\nprint(\"Home Power: %0.2fkW\" % (float(home)/1000.0))\nprint(\"\")\n\n# Raw JSON Payload Examples\nprint(\"Grid raw: %r\\n\" % pw.grid(verbose=True))\nprint(\"Solar raw: %r\\n\" % pw.solar(verbose=True))\n\n# Display Device Vitals\nprint(\"Vitals: %r\\n\" % pw.vitals())\n\n# Display String Data\nprint(\"String Data: %r\\n\" % pw.strings())\n\n# Display System Status (e.g. Battery Capacity)\nprint(\"System Status: %r\\n\" % pw.system_status())\n```\n\n### pyPowerwall Module Class and Functions \n\n```\n set_debug(True, color=True)\n\n Classes\n    Powerwall(host, password, email, timezone, pwcacheexpire, timeout, poolmaxsize,\n        cloudmode, siteid, authpath, authmode, cachefile, fleetapi, auto_select, retry_modes, gw_pwd,\n        rsa_key_path)\n\n Parameters\n    host                      # Hostname or IP of the Tesla gateway; may include :port for non-standard HTTPS (e.g. 10.0.1.99:8443); default port is 443 if omitted\n    password                  # Customer password for gateway\n    email                     # (required) Customer email for gateway / cloud\n    timezone                  # Desired timezone\n    pwcacheexpire = 5         # Set API cache timeout in seconds\n    timeout = 5               # Timeout for HTTPS calls in seconds\n    poolmaxsize = 10          # Pool max size for HTTP connection reuse (persistent\n                                connections disabled if zero)\n    cloudmode = False         # If True, use Tesla cloud for data (default is False)\n    siteid = None             # If cloudmode is True, use this siteid (default is None)\n    authpath = \"\"             # Path to cloud auth and site files (default current directory)\n    authmode = \"cookie\"       # \"cookie\" (default) or \"token\" - use cookie or bearer token for auth\n    cachefile = \".powerwall\"  # Path to cache file (default current directory)\n    fleetapi = False          # If True, use Tesla FleetAPI for data (default is False)\n    auth_path = \"\"            # Path to configfile (default current directory)\n    auto_select = False       # If True, select the best available mode to connect (default is False)\n    retry_modes = False       # If True, retry connection to Powerwall\n    gw_pwd = None             # Full gateway password from QR sticker; used for TEDAPI (mode 4)\n                                and auto-derived (last 5 chars) for v1r login (mode 5)\n    rsa_key_path = None       # Path to RSA-4096 private key for v1r LAN TEDapi (Powerwall 3)\n\n Functions\n   poll(api, json, force)    # Return data from Powerwall API (dict if json=True, bypass cache force=True)\n   post(api, payload, json)  # Send payload to Powerwall API (dict if json=True)\n    level(scale)              # Return battery power level percentage (scale=False: actual level, scale=True: Tesla app level)\n    power()                   # Return power data returned as dictionary\n    site(verbose)             # Return site sensor data (W or raw JSON if verbose=True)\n    solar(verbose):           # Return solar sensor data (W or raw JSON if verbose=True)\n    battery(verbose):         # Return battery sensor data (W or raw JSON if verbose=True)\n    load(verbose)             # Return load sensor data (W or raw JSON if verbose=True)\n    grid()                    # Alias for site()\n    home()                    # Alias for load()\n    vitals(json)              # Return Powerwall device vitals (dict or json if True)\n    strings(json, verbose)    # Return solar panel string data\n    din()                     # Return DIN\n    uptime()                  # Return uptime - string hms format\n    version()                 # Return system version\n    status(param)             # Return status (JSON) or individual param\n    site_name()               # Return site name\n    temps()                   # Return Powerwall Temperatures\n    alerts()                  # Return array of Alerts from devices\n    system_status(json)       # Returns the system status\n    battery_blocks(json)      # Returns battery specific information merged from system_status() and vitals()\n    grid_status(type)         # Return the power grid status, type =\"string\" (default), \"json\", or \"numeric\"\n                              #     - \"string\": \"UP\", \"DOWN\", \"SYNCING\"\n                              #     - \"numeric\": -1 (Syncing), 0 (DOWN), 1 (UP)\n    is_connected()            # Returns True if able to connect and login to Powerwall\n    get_reserve(scale)        # Get Battery Reserve Percentage\n    get_mode()                # Get Current Battery Operation Mode\n    set_reserve(level)        # Set Battery Reserve Percentage\n    set_mode(mode)            # Set Current Battery Operation Mode\n    get_time_remaining()      # Get the backup time remaining on the battery\n    set_operation(level, mode, json)        # Set Battery Reserve Percentage and/or Operation Mode\n    set_grid_charging(mode)   # Enable or disable grid charging (mode = True or False)\n    set_grid_export(mode)     # Set grid export mode (mode = battery_ok, pv_only, never)\n    get_grid_charging()       # Get the current grid charging mode\n    get_grid_export()         # Get the current grid export mode\n```\n\n## Tools\n\nThe following are some useful tools based on pypowerwall:\n\n* [Powerwall Proxy](proxy) - Use this caching proxy to handle authentication to the Powerwall Gateway and make basic read-only API calls to /api/meters/aggregates (power metrics), /api/system_status/soe (battery level) and many [others](https://github.com/jasonacox/pypowerwall/blob/main/proxy/API.md). This is useful for metrics gathering tools like telegraf to pull metrics without needing to authenticate. Because pyPowerwall is designed to cache the auth and high frequency API calls, this will also reduce the load on the Gateway and prevent crash/restart issues that can happen if too many sessions are created on the Gateway.\n\n* [Powerwall Simulator](simulator) - A Powerwall simulator to mimic the responses from the Tesla Powerwall Gateway. This is useful for testing purposes.\n\n* [Powerwall Dashboard](https://github.com/jasonacox/Powerwall-Dashboard#powerwall-dashboard) - Monitoring Dashboard for the Tesla Powerwall using Grafana, InfluxDB, Telegraf and pyPowerwall.\n\n## pyPowerwall Command Line Interface (CLI)\n\npyPowerwall has a built-in feature to scan your network for available Powerwall gateways and set/get operational and reserve modes.\n\n```\nUsage: PyPowerwall [-h] {setup,scan,set,get,version} ...\n\nPyPowerwall Module v0.8.1\n\nOptions:\n  -h, --help            Show this help message and exit\n\nCommands (run \u003ccommand\u003e -h to see usage information):\n  {setup,fleetapi,tedapi,scan,set,get,version}\n    setup                 Setup Tesla Login for Cloud Mode access\n    fleetapi              Setup Tesla FleetAPI for Cloud Mode access\n    tedapi                Test TEDAPI connection to Powerwall Gateway\n    scan                  Scan local network for Powerwall gateway\n    set                   Set Powerwall Mode and Reserve Level\n    get                   Get Powerwall Settings and Power Levels\n    version               Print version information\n\n   set options:\n      -mode MODE          Powerwall Mode: self_consumption, backup, or autonomous\n      -reserve RESERVE    Set Battery Reserve Level [Default=20]\n      -current            Set Battery Reserve Level to Current Charge\n      -gridcharging MODE  Set Grid Charging (allow) Mode (\"on\" or \"off\")\n      -gridexport MODE    Set Export to Grid Mode (\"battery_ok\", \"pv_only\", or \"never\")\n\n   get options:\n      -format FORMAT      Output format: text, json, csv\n      -host HOST          IP address of Powerwall Gateway\n      -password PASSWORD  Password for Powerwall Gateway\n```\n   \n```bash\n# Install pyPowerwall if you haven't already\npython -m pip install pypowerwall\n\n# Scan Network for Powerwalls\npython -m pypowerwall scan\n```\n\nExample Output\n```\npyPowerwall Network Scanner [0.1.2]\nScan local network for Tesla Powerwall Gateways\n\n    Your network appears to be: 10.0.1.0/24\n\n    Enter Network or press enter to use 10.0.1.0/24: \n\n    Running Scan...\n      Host: 10.0.1.16 ... OPEN - Not a Powerwall\n      Host: 10.0.1.26 ... OPEN - Not a Powerwall\n      Host: 10.0.1.36 ... OPEN - Found Powerwall 1232100-00-E--TG123456789ABG\n      Done                           \n\nDiscovered 1 Powerwall Gateway\n     10.0.1.36 [1232100-00-E--TG123456789ABG]\n```\n\nGet Power Levels, Operation Mode, and Battery Reserve Level\n\n```bash\n# Setup Connection with Tesla Cloud\npython -m pypowerwall setup\n\n# Get Power Levels, Operation Mode, and Battery Reserve Setting\n#\n# Usage: PyPowerwall get [-h] [-format FORMAT]\n#  -h, --help      show this help message and exit\n#  -format FORMAT  Output format: text, json, csv\n#\npython -m pypowerwall get\npython -m pypowerwall get -format json\npython -m pypowerwall get -format csv\n\n# Set Operation Mode and Battery Reserve Setting\n#\n# Usage: PyPowerwall set [-h] [-mode MODE] [-reserve RESERVE] [-current]\n#  -h, --help        show this help message and exit\n#  -mode MODE        Powerwall Mode: self_consumption, backup, or autonomous\n#  -reserve RESERVE  Set Battery Reserve Level [Default=20]\n#  -current          Set Battery Reserve Level to Current Charge\n#\npython -m pypowerwall set -mode self_consumption\npython -m pypowerwall set -reserve 30\npython -m pypowerwall set -current\n```\n\n## Example API Calls\n\nThe following APIs are a result of help from other projects as well as my own investigation. \n\n* pw.poll('/api/system_status/soe') - Battery percentage (JSON with float 0-100)\n\n   ```json\n   {\"percentage\":40.96227949234631}\n   ```\n\n* pw.poll('/api/meters/aggregates') - Site, Load, Solar and Battery (JSON)\n\n   ```json\n   {\n      \"site\": {\n         \"last_communication_time\": \"2021-11-22T22:15:06.590577619-07:00\",\n         \"instant_power\": -23,\n         \"instant_reactive_power\": -116,\n         \"instant_apparent_power\": 118.25819210524064,\n         \"frequency\": 0,\n         \"energy_exported\": 3826.313294918422,\n         \"energy_imported\": 1302981.2128324094,\n         \"instant_average_voltage\": 209.59546822390985,\n         \"instant_average_current\": 5.4655000000000005,\n         \"i_a_current\": 0,\n         \"i_b_current\": 0,\n         \"i_c_current\": 0,\n         \"last_phase_voltage_communication_time\": \"0001-01-01T00:00:00Z\",\n         \"last_phase_power_communication_time\": \"0001-01-01T00:00:00Z\",\n         \"timeout\": 1500000000,\n         \"num_meters_aggregated\": 1,\n         \"instant_total_current\": 5.4655000000000005\n      },\n      \"battery\": {\n         \"last_communication_time\": \"2021-11-22T22:15:06.590178016-07:00\",\n         \"instant_power\": 1200,\n         \"instant_reactive_power\": 0,\n         \"instant_apparent_power\": 1200,\n         \"frequency\": 59.997,\n         \"energy_exported\": 635740,\n         \"energy_imported\": 730610,\n         \"instant_average_voltage\": 242.15000000000003,\n         \"instant_average_current\": -28.6,\n         \"i_a_current\": 0,\n         \"i_b_current\": 0,\n         \"i_c_current\": 0,\n         \"last_phase_voltage_communication_time\": \"0001-01-01T00:00:00Z\",\n         \"last_phase_power_communication_time\": \"0001-01-01T00:00:00Z\",\n         \"timeout\": 1500000000,\n         \"num_meters_aggregated\": 2,\n         \"instant_total_current\": -28.6\n      },\n      \"load\": {\n         \"last_communication_time\": \"2021-11-22T22:15:06.590178016-07:00\",\n         \"instant_power\": 1182.5,\n         \"instant_reactive_power\": -130.5,\n         \"instant_apparent_power\": 1189.6791584288599,\n         \"frequency\": 0,\n         \"energy_exported\": 0,\n         \"energy_imported\": 2445454.899537491,\n         \"instant_average_voltage\": 209.59546822390985,\n         \"instant_average_current\": 5.641820455472543,\n         \"i_a_current\": 0,\n         \"i_b_current\": 0,\n         \"i_c_current\": 0,\n         \"last_phase_voltage_communication_time\": \"0001-01-01T00:00:00Z\",\n         \"last_phase_power_communication_time\": \"0001-01-01T00:00:00Z\",\n         \"timeout\": 1500000000,\n         \"instant_total_current\": 5.641820455472543\n      },\n      \"solar\": {\n         \"last_communication_time\": \"2021-11-22T22:15:06.594908129-07:00\",\n         \"instant_power\": 10,\n         \"instant_reactive_power\": 0,\n         \"instant_apparent_power\": 10,\n         \"frequency\": 59.988,\n         \"energy_exported\": 1241170,\n         \"energy_imported\": 0,\n         \"instant_average_voltage\": 241.60000000000002,\n         \"instant_average_current\": 0.04132231404958678,\n         \"i_a_current\": 0,\n         \"i_b_current\": 0,\n         \"i_c_current\": 0,\n         \"last_phase_voltage_communication_time\": \"0001-01-01T00:00:00Z\",\n         \"last_phase_power_communication_time\": \"0001-01-01T00:00:00Z\",\n         \"timeout\": 1000000000,\n         \"num_meters_aggregated\": 1,\n         \"instant_total_current\": 0.04132231404958678\n      }\n   }\n   ```\n\n* pw.strings(jsonformat=True)\n\n   ```json \n   {\n      \"A\": {\n         \"Connected\": true,\n         \"Current\": 1.81,\n         \"Power\": 422.0,\n         \"State\": \"PV_Active\",\n         \"Voltage\": 230.0\n      },\n      \"B\": {\n         \"Connected\": false,\n         \"Current\": 0.0,\n         \"Power\": 0.0,\n         \"State\": \"PV_Active\",\n         \"Voltage\": -2.5\n      },\n      \"C\": {\n         \"Connected\": true,\n         \"Current\": 4.47,\n         \"Power\": 892.0,\n         \"State\": \"PV_Active\",\n         \"Voltage\": 202.4\n      },\n      \"D\": {\n         \"Connected\": true,\n         \"Current\": 4.44,\n         \"Power\": 889.0,\n         \"State\": \"PV_Active_Parallel\",\n         \"Voltage\": 202.10000000000002\n      }\n   }\n   ```\n\n* pw.temps(jsonformat=True)\n\n   ```json\n   {\n      \"TETHC--2012170-25-E--TGxxxxxxxxxxxx\": 17.5,\n      \"TETHC--3012170-05-B--TGxxxxxxxxxxxx\": 17.700000000000003\n   }\n   ```\n\n* pw.status(jsonformat=True)\n\n   ```json\n   {\n      \"din\": \"1232100-00-E--TGxxxxxxxxxxxx\",\n      \"start_time\": \"2022-01-05 09:20:47 +0800\",\n      \"up_time_seconds\": \"62h48m24.076725628s\",\n      \"is_new\": false,\n      \"version\": \"21.44.1 c58c2df3\",\n      \"git_hash\": \"c58c2df39ec207708c4cde0c747db7cf31750f29\",\n      \"commission_count\": 8,\n      \"device_type\": \"teg\",\n      \"sync_type\": \"v2.1\",\n      \"leader\": \"\",\n      \"followers\": null,\n      \"cellular_disabled\": false\n   }\n   ```\n* pw.vitals(jsonformat=True)\n\n   * Example Output: [here](https://github.com/jasonacox/pypowerwall/blob/main/docs/vitals-example.json)\n   * Produces device vitals and alerts. For more information see [here](https://github.com/jasonacox/pypowerwall/tree/main/docs#devices-and-alerts).\n\n* pw.grid_status(type=\"json\")\n\n   ```json\n   {\n    \"grid_services_active\": false,\n    \"grid_status\": \"SystemGridConnected\"\n   }\n   ```\n* pw.system_status(jsonformat=True)\n\n   ```json\n   {\n    \"all_enable_lines_high\": true,\n    \"auxiliary_load\": 0,\n    \"available_blocks\": 2,\n    \"battery_blocks\": [\n        {\n            \"OpSeqState\": \"Active\",\n            \"PackagePartNumber\": \"3012170-10-B\",\n            \"PackageSerialNumber\": \"TG122xxx\", \n            \"Type\": \"\",\n            \"backup_ready\": true,\n            \"charge_power_clamped\": false,\n            \"disabled_reasons\": [],\n            \"energy_charged\": 21410,\n            \"energy_discharged\": 950,\n            \"f_out\": 60.016999999999996,\n            \"i_out\": 6.800000000000001,\n            \"nominal_energy_remaining\": 13755,\n            \"nominal_full_pack_energy\": 13803,\n            \"off_grid\": false,\n            \"p_out\": -370,\n            \"pinv_grid_state\": \"Grid_Compliant\",\n            \"pinv_state\": \"PINV_GridFollowing\",\n            \"q_out\": -10,\n            \"v_out\": 243.60000000000002,\n            \"version\": \"b0ec24329c08e4\",\n            \"vf_mode\": false,\n            \"wobble_detected\": false\n        },\n        {\n            \"OpSeqState\": \"Active\",\n            \"PackagePartNumber\": \"3012170-10-B\",\n            \"PackageSerialNumber\": \"TG122yyy\", \n            \"Type\": \"\",\n            \"backup_ready\": true,\n            \"charge_power_clamped\": false,\n            \"disabled_reasons\": [],\n            \"energy_charged\": 20460,\n            \"energy_discharged\": 1640,\n            \"f_out\": 60.016000000000005,\n            \"i_out\": 3.6,\n            \"nominal_energy_remaining\": 13789,\n            \"nominal_full_pack_energy\": 13816,\n            \"off_grid\": false,\n            \"p_out\": -210,\n            \"pinv_grid_state\": \"Grid_Compliant\",\n            \"pinv_state\": \"PINV_GridFollowing\",\n            \"q_out\": 20,\n            \"v_out\": 243.20000000000002,\n            \"version\": \"b0ec24329c08e4\",\n            \"vf_mode\": false,\n            \"wobble_detected\": false\n        }\n    ],\n    \"battery_target_power\": -706,\n    \"battery_target_reactive_power\": 0,\n    \"blocks_controlled\": 2,\n    \"can_reboot\": \"Yes\",\n    \"command_source\": \"Configuration\",\n    \"expected_energy_remaining\": 0,\n    \"ffr_power_availability_high\": 11658,\n    \"ffr_power_availability_low\": 194,\n    \"grid_faults\": [\n        {\n            \"alert_is_fault\": false,\n            \"alert_name\": \"PINV_a006_vfCheckUnderFrequency\",\n            \"alert_raw\": 432374469357469696,\n            \"decoded_alert\": \"[{\\\"name\\\":\\\"PINV_alertID\\\",\\\"value\\\":\\\"PINV_a006_vfCheckUnderFrequency\\\"},{\\\"name\\\":\\\"PINV_alertType\\\",\\\"value\\\":\\\"Warning\\\"},{\\\"name\\\":\\\"PINV_a006_frequency\\\",\\\"value\\\":58.97,\\\"units\\\":\\\"Hz\\\"}]\",\n            \"ecu_package_part_number\": \"1081100-22-U\",\n            \"ecu_package_serial_number\": \"CN321365D2U06J\",\n            \"ecu_type\": \"TEPINV\",\n            \"git_hash\": \"b0ec24329c08e4\",\n            \"site_uid\": \"1232100-00-E--TG120325001C3D\",\n            \"timestamp\": 1645733844019\n        }\n    ],\n    \"grid_services_power\": 0,\n    \"instantaneous_max_apparent_power\": 30690,\n    \"instantaneous_max_charge_power\": 14000,\n    \"instantaneous_max_discharge_power\": 20000,\n    \"inverter_nominal_usable_power\": 11700,\n    \"last_toggle_timestamp\": \"2022-02-22T08:18:22.51778899-07:00\",\n    \"load_charge_constraint\": 0,\n    \"max_apparent_power\": 10000,\n    \"max_charge_power\": 10000,\n    \"max_discharge_power\": 10000,\n    \"max_power_energy_remaining\": 0,\n    \"max_power_energy_to_be_charged\": 0,\n    \"max_sustained_ramp_rate\": 2512500,\n    \"nominal_energy_remaining\": 27624,\n    \"nominal_full_pack_energy\": 27668,\n    \"primary\": true,\n    \"score\": 10000,\n    \"smart_inv_delta_p\": 0,\n    \"smart_inv_delta_q\": 0,\n    \"solar_real_power_limit\": -1,\n    \"system_island_state\": \"SystemGridConnected\"\n   }\n   ```\n\n* pw.battery_blocks(jsonformat=True)\n\n   ```json\n   {  \n      \"TG122xxx\": {\n         \"OpSeqState\": \"Active\",\n         \"PackagePartNumber\": \"3012170-10-B\",\n         \"THC_State\": \"THC_STATE_AUTONOMOUSCONTROL\",\n         \"Type\": \"\",\n         \"backup_ready\": true,\n         \"charge_power_clamped\": false,\n         \"disabled_reasons\": [],\n         \"energy_charged\": 21020,\n         \"energy_discharged\": 880,\n         \"f_out\": 60.016000000000005,\n         \"i_out\": 2.7,\n         \"nominal_energy_remaining\": 13812,\n         \"nominal_full_pack_energy\": 13834,\n         \"off_grid\": false,\n         \"p_out\": -160,\n         \"pinv_grid_state\": \"Grid_Compliant\",\n         \"pinv_state\": \"PINV_GridFollowing\",\n         \"q_out\": 20,\n         \"temperature\": 21.799999999999997,\n         \"v_out\": 243.9,\n         \"version\": \"b0ec24329c08e4\",\n         \"vf_mode\": false,\n         \"wobble_detected\": false\n      },\n      \"TG122yyy\": {\n         \"OpSeqState\": \"Active\",\n         \"PackagePartNumber\": \"3012170-10-B\",\n         \"THC_State\": \"THC_STATE_AUTONOMOUSCONTROL\",\n         \"Type\": \"\",\n         \"backup_ready\": true,\n         \"charge_power_clamped\": false,\n         \"disabled_reasons\": [],\n         \"energy_charged\": 21020,\n         \"energy_discharged\": 880,\n         \"f_out\": 60.016000000000005,\n         \"i_out\": 2.7,\n         \"nominal_energy_remaining\": 13812,\n         \"nominal_full_pack_energy\": 13834,\n         \"off_grid\": false,\n         \"p_out\": -160,\n         \"pinv_grid_state\": \"Grid_Compliant\",\n         \"pinv_state\": \"PINV_GridFollowing\",\n         \"q_out\": 20,\n         \"temperature\": 18.5,\n         \"v_out\": 243.9,\n         \"version\": \"b0ec24329c08e4\",\n         \"vf_mode\": false,\n         \"wobble_detected\": false\n      }\n   }\n   ```\n\n\n## Documentation\n\nFor detailed documentation, see the [Documentation Hub](docs/README.md).\n\n### Quick Reference\n\n* [Firmware Version History](docs/reference/firmware-history.md) - Complete history of Powerwall firmware versions and release notes\n* [Device Information](docs/reference/devices.md) - Detailed information about Powerwall devices and alerts  \n* [Alert Codes](docs/reference/alerts.md) - Comprehensive list of alert codes\n* [Python API Reference](API.md) - Full API documentation\n\n## Glossary\n\nThis is an unofficial list of terms that are seen in Powerwall responses and messages. \n\n* Site = Utility Grid\n* Load = Home (think of it as the \"load\" that the battery or grid powers)\n* instant_power = Current power (instant) - also called \"true power\" in wattage (W)\n* instant_reactive_power = The dissipated power resulting from inductive and capacitive loads measured in volt-amperes reactive (VAR)\n* instant_apparent_power = The combination of reactive and true power measure in volt-amperes (VA)\n* energy_imported = kWh pulled from grid over a duration of time (since Powerwall commissioning it seems)\n* energy_exported = kWh pushed to grid\n\n### Support\n\nThere are several ways you can support this project.\n\n* Submit ideas, issues, discussions and code! Thanks to our active community, the project continues to grow and improve. Your engagement and help is needed and appreciated.\n* Tell others. If you find this useful, please share with others to help build our community.\n* Help test the code. We need help testing the project on different platforms and systems. Report your finding and any suggestions to make it easier to better.\n* Some of you have asked how you can contribute to help fund the project. This is work of love and a hobby. I'm not looking for financial help. However, if you are considering purchasing a Tesla Solar and/or Powerwall system, please take advantage of this code for a discount and I'll get a referral credit as well: https://www.tesla.com/referral/jason50054\n\n## References\n\n* Tesla Powerwall 2 – Local Gateway API documentation – https://github.com/vloschiavo/powerwall2\n* TESLA PowerWall 2 Security Shenanigans – https://github.com/hackerschoice/thc-tesla-powerwall2-hack\n* Powerwall Monitoring – https://github.com/mihailescu2m/powerwall_monitor\n* Protocol Buffers (protobuf) Basics - https://developers.google.com/protocol-buffers/docs/pythontutorial\n* Powerwall Dashboard - The project that started pypowerwall - https://github.com/jasonacox/Powerwall-Dashboard\n\n# Acknowledgements\n\n* [Tesla Energy](https://www.tesla.com/energy/design?referral=jason50054\u0026redirect=no) - Tesla is not affiliated with this project but we want to thank the brilliant minds at Tesla for creating such a great system for solar home energy generation. Tesla and Powerwall are trademarks of Tesla, Inc.\n* Tesla ([tesla.proto](tesla.proto)) Research and Credit to @brianhealey\n* Status Functions - Thanks to @wcwong for contribution: system_status(), battery_blocks(), grid_status()\n* Special thanks to the entire pypowerwall community for the great engagement, contributions and encouragement! See [RELEASE notes](https://github.com/jasonacox/pypowerwall/releases) for the ever growing list of improvements and contributors making this project possible.\n\n## Other Tools and Similar Projects\n\n* NetZero app - iOS and Android App for monitoring your System - https://www.netzeroapp.io/\n* Python Tesla Powerwall API – https://github.com/jrester/tesla_powerwall\n* GoTesla - go based Tesla API - https://github.com/bmah888/gotesla\n\n## Contributors\n\n\u003ca href=\"https://github.com/jasonacox/pypowerwall/graphs/contributors\"\u003e\n  \u003cimg src=\"https://contrib.rocks/image?repo=jasonacox/pypowerwall\" /\u003e\n\u003c/a\u003e\n\n## Citation\n\nIf you wish to cite this project, please use:\n\n```bibtex\n@software{pyPowerwall,\n  author = {Cox, Jason A.},\n  title = {pyPowerwall: Python API for Tesla Powerwall and Solar Energy Data.},\n  year = {2023},\n  publisher = {GitHub},\n  journal = {GitHub repository},\n  howpublished = {\\url{https://github.com/jasonacox/pypowerwall}},\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjasonacox%2Fpypowerwall","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjasonacox%2Fpypowerwall","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjasonacox%2Fpypowerwall/lists"}