Skip to content

Commit

Permalink
Fix exceptions and invalid return data
Browse files Browse the repository at this point in the history
  • Loading branch information
mcbirse committed Dec 29, 2023
1 parent 9cfd58d commit 41cff9a
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 40 deletions.
52 changes: 30 additions & 22 deletions proxy/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,9 @@ def get_value(a, key):
if siteid is not None and siteid != str(pw.Tesla.siteid):
log.info("Switch to Site %s" % siteid)
if not pw.Tesla.change_site(siteid):
log.error("Fatal Error: Unable to initialize pyPowerwall")
os._exit(1)
log.error("Fatal Error: Unable to connect. Please fix config and restart.")
while True:
time.sleep(5) # Infinite loop to keep container running
else:
log.info("pyPowerwall Proxy Server - Connected to %s" % host)

Expand Down Expand Up @@ -232,18 +233,21 @@ def do_GET(self):
# Alerts
message = pw.alerts(jsonformat=True)
elif self.path == '/alerts/pw':
# Alerts in dictionary/object format
pwalerts = {}
idx = 1
alerts = pw.alerts()
for alert in alerts:
pwalerts[alert] = 1
message = json.dumps(pwalerts)
# Alerts in dictionary/object format
pwalerts = {}
idx = 1
alerts = pw.alerts()
if alerts is None:
message = None
else:
for alert in alerts:
pwalerts[alert] = 1
message = json.dumps(pwalerts)
elif self.path == '/freq':
# Frequency, Current, Voltage and Grid Status
fcv = {}
idx = 1
vitals = pw.vitals()
vitals = pw.vitals() or {}
for device in vitals:
d = vitals[device]
if device.startswith('TEPINV'):
Expand All @@ -264,7 +268,7 @@ def do_GET(self):
# Battery Data
pod = {}
idx = 1
vitals = pw.vitals()
vitals = pw.vitals() or {}
for device in vitals:
d = vitals[device]
if device.startswith('TEPOD'):
Expand All @@ -283,23 +287,27 @@ def do_GET(self):
pod["PW%d_POD_nom_full_pack_energy" % idx] = get_value(d, 'POD_nom_full_pack_energy')
idx = idx + 1
pod["backup_reserve_percent"] = pw.get_reserve()
d = pw.system_status()
d = pw.system_status() or {}
pod["nominal_full_pack_energy"] = get_value(d,'nominal_full_pack_energy')
pod["nominal_energy_remaining"] = get_value(d,'nominal_energy_remaining')
pod["time_remaining_hours"] = pw.get_time_remaining()
message = json.dumps(pod)
elif self.path == '/version':
# Firmware Version
v = {}
v["version"] = pw.version()
val = pw.version().split(" ")[0]
val = ''.join(i for i in val if i.isdigit() or i in './\\')
while len(val.split('.')) < 3:
val = val + ".0"
l = [int(x, 10) for x in val.split('.')]
l.reverse()
v["vint"] = sum(x * (100 ** i) for i, x in enumerate(l))
message = json.dumps(v)
version = pw.version()
if version is None:
message = None
else:
v = {}
v["version"] = version
val = v["version"].split(" ")[0]
val = ''.join(i for i in val if i.isdigit() or i in './\\')
while len(val.split('.')) < 3:
val = val + ".0"
l = [int(x, 10) for x in val.split('.')]
l.reverse()
v["vint"] = sum(x * (100 ** i) for i, x in enumerate(l))
message = json.dumps(v)
elif self.path == '/help':
# Display friendly help screen link and stats
proxystats['ts'] = int(time.time())
Expand Down
38 changes: 20 additions & 18 deletions pypowerwall/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,14 +286,13 @@ def level(self, scale=False):
Note: Tesla App reserves 5% of battery = ( (batterylevel / 0.95) - (5 / 0.95) )
"""
# Return power level percentage for battery
level = 0
payload = self.poll('/api/system_status/soe', jsonformat=True)
if(payload is not None and 'percentage' in payload):
if payload is not None and 'percentage' in payload:
level = payload['percentage']
if scale:
return ((level / 0.95) - (5 / 0.95))
else:
if scale:
level = (level / 0.95) - (5 / 0.95)
return level
return None

def power(self):
"""
Expand Down Expand Up @@ -543,6 +542,8 @@ def status(self, param=None, jsonformat=False):
cellular_disabled = payload['cellular_disabled']
"""
payload = self.poll('/api/status', jsonformat=True)
if payload is None:
return None
if param is None:
if jsonformat:
return json.dumps(payload, indent=4, sort_keys=True)
Expand Down Expand Up @@ -616,15 +617,14 @@ def get_reserve(self, scale=True):
scale = If True (default) use Tesla's 5% reserve calculation
Tesla App reserves 5% of battery = ( (batterylevel / 0.95) - (5 / 0.95) )
"""
data = self.poll('/api/operation')
if data is None:
return None
data = json.loads(data)
percent = float(data['backup_reserve_percent'])
if scale:
# Get percentage based on Tesla App scale
percent = float((percent / 0.95) - (5 / 0.95))
return percent
data = self.poll('/api/operation', jsonformat=True)
if data is not None and 'backup_reserve_percent' in data:
percent = float(data['backup_reserve_percent'])
if scale:
# Get percentage based on Tesla App scale
percent = float((percent / 0.95) - (5 / 0.95))
return percent
return None

def grid_status(self, type="string"):
"""
Expand Down Expand Up @@ -655,7 +655,7 @@ def grid_status(self, type="string"):
return gridmap[grid_status][type]
except:
# The payload from powerwall was not valid
log.debug("ERROR Invalid return value received from gateway: " + str(payload.grid_status))
log.debug('ERROR unable to parse payload for grid_status: %r' % payload)
return None

def system_status(self, jsonformat=False):
Expand Down Expand Up @@ -767,9 +767,11 @@ def get_time_remaining(self):
return d['response']['time_remaining_hours']

# Compute based on battery level and load
d = self.system_status()
if 'nominal_energy_remaining' in d:
return d['nominal_energy_remaining']/self.load()
d = self.system_status() or {}
if 'nominal_energy_remaining' in d and d['nominal_energy_remaining'] is not None:
load = self.load() or 0
if load > 0:
return d['nominal_energy_remaining']/load
# Default
return None

0 comments on commit 41cff9a

Please sign in to comment.