diff --git a/README.md b/README.md index b366aa6..6c1a6e1 100644 --- a/README.md +++ b/README.md @@ -347,6 +347,8 @@ Supported control operations: |---------|--------|--------| | Backup reserve | `set_reserve(level)` | 0-100 (percentage) | | Operation mode | `set_mode(mode)` | `self_consumption`, `backup` | + +> **Cloud/FleetAPI Reserve Limit:** Tesla's cloud APIs enforce a maximum backup reserve of 80%. If you need to set the reserve above 80% (e.g., for a full charge before an outage), use the v1r LAN mode shown below. The `set` CLI will print a warning when you attempt to exceed 80% in cloud or FleetAPI mode. | Grid charging | `set_grid_charging(enable)` | `True` / `False` | | Grid export | `set_grid_export(mode)` | `battery_ok`, `pv_only`, `never` | @@ -597,7 +599,7 @@ print("System Status: %r\n" % pw.system_status()) is_connected() # Returns True if able to connect and login to Powerwall get_reserve(scale) # Get Battery Reserve Percentage get_mode() # Get Current Battery Operation Mode - set_reserve(level) # Set Battery Reserve Percentage + set_reserve(level) # Set Battery Reserve Percentage (cloud/FleetAPI max 80% - use v1r for higher) set_mode(mode) # Set Current Battery Operation Mode get_time_remaining() # Get the backup time remaining on the battery set_operation(level, mode, json) # Set Battery Reserve Percentage and/or Operation Mode @@ -743,6 +745,11 @@ python -m pypowerwall set -reserve 20 # Set reserve to current charge level python -m pypowerwall set -current +# ⚠️ Cloud and FleetAPI modes limit backup reserve to 80% max. +# To set reserve above 80%, use v1r LAN mode: +python -m pypowerwall set -v1r -host 10.42.1.40 -gw_pwd ABCDEXXXXX \ + -rsa_key_path ./tedapi_rsa_private.pem -reserve 100 + # Grid charging and export python -m pypowerwall set -gridcharging on python -m pypowerwall set -gridcharging off diff --git a/RELEASE.md b/RELEASE.md index 4c7b964..c59cfa4 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -2,6 +2,10 @@ ## v0.15.7 - Grid Noise Suppression and v1r Owner API Login Fix +* Docs: Document Tesla cloud/FleetAPI 80% backup reserve limit + * Added warning in README and CLI examples for `set -reserve` when using cloud or FleetAPI mode + * CLI now prints a WARNING when attempting to set reserve above 80% in cloud/FleetAPI mode, and a NOTE if Tesla caps the actual value + * Added v1r LAN mode example showing how to set reserve above 80% * Feat: Add `PW_SITE_ZERO_THRESHOLD` environment variable to suppress phantom grid noise readings * When set to a positive integer value (in watts), site power readings with absolute value at or below the threshold are reported as 0 * Applies to `/api/meters/aggregates` site power, `/csv`/`/csv/v2` grid power, and `/json` grid power endpoints diff --git a/pypowerwall/__main__.py b/pypowerwall/__main__.py index a42647f..d9fc09a 100644 --- a/pypowerwall/__main__.py +++ b/pypowerwall/__main__.py @@ -448,12 +448,28 @@ def main(): pw.set_mode(mode) if args.reserve != -1: reserve = args.reserve + if reserve > 80 and pw.mode in ('cloud', 'fleetapi'): + print(f"WARNING: Tesla cloud/FleetAPI limits backup reserve to 80% max. " + f"Requesting {reserve}% but Tesla may cap it at 80%. " + f"Use TEDAPI v1r mode (-v1r) to set reserve above 80%.") print("Setting Powerwall Reserve to %s" % reserve) pw.set_reserve(reserve) + if reserve > 80 and pw.mode in ('cloud', 'fleetapi'): + actual = pw.get_reserve(scale=True, force=True) + if actual is not None and actual <= 80: + print(f"NOTE: Tesla capped reserve at {actual}% instead of {reserve}%.") if args.current: current = float(pw.level()) + if current > 80 and pw.mode in ('cloud', 'fleetapi'): + print(f"WARNING: Tesla cloud/FleetAPI limits backup reserve to 80% max. " + f"Current charge is {current:.0f}% but Tesla may cap reserve at 80%. " + f"Use TEDAPI v1r mode (-v1r) to set reserve above 80%.") print("Setting Powerwall Reserve to Current Charge Level %s" % current) pw.set_reserve(current) + if current > 80 and pw.mode in ('cloud', 'fleetapi'): + actual = pw.get_reserve(scale=True, force=True) + if actual is not None and actual <= 80: + print(f"NOTE: Tesla capped reserve at {actual}% instead of {current:.0f}%.") if args.gridcharging: gridcharging = args.gridcharging.lower() if gridcharging not in ['on', 'off']: