-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #101 from jasonacox/v0.10.4
Add Powerwall 3 Local API Support
- Loading branch information
Showing
13 changed files
with
1,013 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
pypowerwall==0.10.3 | ||
pypowerwall==0.10.4 | ||
bs4==0.0.2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -55,7 +55,7 @@ | |
from transform import get_static, inject_js | ||
from urllib.parse import urlparse, parse_qs | ||
|
||
BUILD = "t60" | ||
BUILD = "t61" | ||
ALLOWLIST = [ | ||
'/api/status', '/api/site_info/site_name', '/api/meters/site', | ||
'/api/meters/solar', '/api/sitemaster', '/api/powerwalls', | ||
|
@@ -74,7 +74,7 @@ | |
# Configuration for Proxy - Check for environmental variables | ||
# and always use those if available (required for Docker) | ||
bind_address = os.getenv("PW_BIND_ADDRESS", "") | ||
password = os.getenv("PW_PASSWORD", "password") | ||
password = os.getenv("PW_PASSWORD", "") | ||
email = os.getenv("PW_EMAIL", "[email protected]") | ||
host = os.getenv("PW_HOST", "") | ||
timezone = os.getenv("PW_TIMEZONE", "America/Los_Angeles") | ||
|
@@ -114,6 +114,7 @@ | |
'cloudmode': False, | ||
'fleetapi': False, | ||
'tedapi': False, | ||
'tedapi_mode': "off", | ||
'siteid': None, | ||
'counter': 0 | ||
} | ||
|
@@ -206,7 +207,8 @@ def get_value(a, key): | |
log.info("Connected to Energy Gateway %s (%s)" % (host, site_name.strip())) | ||
if pw.tedapi: | ||
proxystats['tedapi'] = True | ||
log.info("TEDAPI Mode Enabled for Device Vitals") | ||
proxystats['tedapi_mode'] = pw.tedapi_mode | ||
log.info(f"TEDAPI Mode Enabled for Device Vitals ({pw.tedapi_mode})") | ||
|
||
pw_control = None | ||
if control_secret: | ||
|
@@ -635,24 +637,30 @@ def do_GET(self): | |
proxy_path = proxy_path[1:] | ||
pw_url = "https://{}/{}".format(pw.host, proxy_path) | ||
log.debug("Proxy request to: {}".format(pw_url)) | ||
if pw.authmode == "token": | ||
r = pw.client.session.get( | ||
url=pw_url, | ||
headers=pw.auth, | ||
verify=False, | ||
stream=True, | ||
timeout=pw.timeout | ||
) | ||
else: | ||
r = pw.client.session.get( | ||
url=pw_url, | ||
cookies=pw.auth, | ||
verify=False, | ||
stream=True, | ||
timeout=pw.timeout | ||
) | ||
fcontent = r.content | ||
ftype = r.headers['content-type'] | ||
try: | ||
if pw.authmode == "token": | ||
r = pw.client.session.get( | ||
url=pw_url, | ||
headers=pw.auth, | ||
verify=False, | ||
stream=True, | ||
timeout=pw.timeout | ||
) | ||
else: | ||
r = pw.client.session.get( | ||
url=pw_url, | ||
cookies=pw.auth, | ||
verify=False, | ||
stream=True, | ||
timeout=pw.timeout | ||
) | ||
fcontent = r.content | ||
ftype = r.headers['content-type'] | ||
except AttributeError as e: | ||
# Display 404 | ||
log.debug("File not found: {}".format(self.path)) | ||
fcontent = bytes("Not Found", 'utf-8') | ||
ftype = "text/plain" | ||
|
||
# Allow browser caching, if user permits, only for CSS, JavaScript and PNG images... | ||
if browser_cache > 0 and (ftype == 'text/css' or ftype == 'application/javascript' or ftype == 'image/png'): | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -84,7 +84,7 @@ | |
from typing import Union, Optional | ||
import time | ||
|
||
version_tuple = (0, 10, 3) | ||
version_tuple = (0, 10, 4) | ||
version = __version__ = '%d.%d.%d' % version_tuple | ||
__author__ = 'jasonacox' | ||
|
||
|
@@ -97,6 +97,7 @@ | |
from pypowerwall.local.pypowerwall_local import PyPowerwallLocal | ||
from pypowerwall.fleetapi.pypowerwall_fleetapi import PyPowerwallFleetAPI | ||
from pypowerwall.pypowerwall_base import parse_version, PyPowerwallBase | ||
from pypowerwall.tedapi.pypowerwall_tedapi import PyPowerwallTEDAPI | ||
from pypowerwall.fleetapi.fleetapi import CONFIGFILE | ||
from pypowerwall.cloud.pypowerwall_cloud import AUTHFILE | ||
|
||
|
@@ -171,6 +172,7 @@ def __init__(self, host="", password="", email="[email protected]", | |
self.mode = "unknown" | ||
self.gw_pwd = gw_pwd # TEG Gateway password for TEDAPI mode | ||
self.tedapi = False | ||
self.tedapi_mode = "off" # off, full, hybrid | ||
|
||
# Make certain assumptions here | ||
if not self.host: | ||
|
@@ -230,16 +232,28 @@ def connect(self, retry=False) -> bool: | |
time.sleep(30) | ||
count = 0 | ||
if self.mode == "local": | ||
log.debug(f"password = {self.password}, gw_pwd = {self.gw_pwd}") | ||
try: | ||
self.client = PyPowerwallLocal(self.host, self.password, self.email, self.timezone, self.timeout, | ||
if not self.password and self.gw_pwd: # Use full TEDAPI mode | ||
log.debug("TEDAPI ** full **") | ||
self.tedapi_mode = "full" | ||
self.client = PyPowerwallTEDAPI(self.gw_pwd, pwcacheexpire=self.pwcacheexpire, | ||
timeout=self.timeout, host=self.host) | ||
else: | ||
self.tedapi_mode = "hybrid" | ||
self.client = PyPowerwallLocal(self.host, self.password, self.email, self.timezone, self.timeout, | ||
self.pwcacheexpire, self.poolmaxsize, self.authmode, self.cachefile, | ||
self.gw_pwd) | ||
self.client.authenticate() | ||
self.cloudmode = self.fleetapi = False | ||
self.tedapi = self.client.tedapi | ||
if not self.tedapi: | ||
self.tedapi_mode = "off" | ||
return True | ||
except Exception as exc: | ||
log.debug(f"Failed to connect using Local mode: {exc} - trying fleetapi mode.") | ||
self.tedapi = False | ||
self.tedapi_mode = "off" | ||
self.mode = "fleetapi" | ||
continue | ||
if self.mode == "fleetapi": | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import functools | ||
import logging | ||
|
||
log = logging.getLogger('pypowerwall.tedapi.pypowerwall_tedapi') | ||
WARNED_ONCE = {} | ||
|
||
|
||
def not_implemented_mock_data(func): | ||
@functools.wraps(func) | ||
def wrapper(*args, **kwargs): | ||
if not WARNED_ONCE.get(func.__name__): | ||
log.warning(f"This API [{func.__name__}] is using mock data in tedapi mode. This message will be " | ||
"printed only once at the warning level.") | ||
WARNED_ONCE[func.__name__] = 1 | ||
else: | ||
log.debug(f"This API [{func.__name__}] is using mock data in tedapi mode.") | ||
return func(*args, **kwargs) | ||
|
||
return wrapper |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
class PyPowerwallTEDAPINoTeslaAuthFile(Exception): | ||
pass | ||
|
||
|
||
class PyPowerwallTEDAPITeslaNotConnected(Exception): | ||
pass | ||
|
||
|
||
class PyPowerwallTEDAPINotImplemented(Exception): | ||
pass | ||
|
||
|
||
class PyPowerwallTEDAPIInvalidPayload(Exception): | ||
pass |
Oops, something went wrong.