Browse Source

Add retries for fetching the usage data

I keep getting 500 errors causing the entire thing to fail. Including
some retries to account for this and hopefully allow the request to
succeed.
Jason Tarka 11 months ago
parent
commit
44d021b5ae
1 changed files with 35 additions and 5 deletions
  1. 35 5
      main.py

+ 35 - 5
main.py

@@ -11,6 +11,8 @@
 
 import pyemvue
 import json
+import time
+import sys
 
 from pyemvue.enums import Scale, Unit
 from pyemvue import PyEmVue
@@ -20,6 +22,10 @@ from datetime import datetime, timezone, timedelta
 NOW = datetime.now(timezone.utc) - timedelta(minutes=2)
 DAYS_BACK = 14 # Number of days in the past to get per-minute data for.
 MAX_HOURS = 12 # The maxinum number of hours that can be retrieved at once.
+MAX_ATTEMPTS = 5
+
+def eprint(*args, **kwargs):
+    print(*args, file=sys.stderr, **kwargs)
 
 # Get & display minutely data for all devices.
 def allUsageOverTime(vue: PyEmVue):
@@ -38,11 +44,9 @@ def channelUsageOverTime(vue: PyEmVue, c):
 	start_time = NOW - timedelta(days=DAYS_BACK)
 	end_time = start_time + timedelta(hours=MAX_HOURS)
 	while start_time < NOW:
-		usage_over_time, start = vue.get_chart_usage(
-				c,
-				start_time, end_time,
-				scale=Scale.MINUTE.value,
-				unit=Unit.KWH.value
+		usage_over_time, start = getChartUsage(
+				vue, c,
+				start_time, end_time
 			)
 		time = start
 		for kwh in usage_over_time:
@@ -57,6 +61,32 @@ def channelUsageOverTime(vue: PyEmVue, c):
 		start_time = end_time
 		end_time += timedelta(minutes=(MAX_HOURS*60))
 
+def getChartUsage(vue: PyEmVue, channel, start_time, end_time):
+	"""
+	Get per-minute usage for the channel, with up to MAX_ATTEMPTS
+	attempts to account for errors.
+	"""
+	attempt = 0
+	while True:
+		attempt += 1
+		try:
+			return vue.get_chart_usage(
+					channel,
+					start_time, end_time,
+					scale=Scale.MINUTE.value,
+					unit=Unit.KWH.value
+				)
+		except Exception as e:
+			if attempt < MAX_ATTEMPTS:
+				eprint(
+					f'Attempt {attempt} for channel {channel.name}',
+					f'from {start_time} to {end_time}',
+					f'failed:', e)
+				time.sleep(5)
+			else:
+				eprint(f'Failed after {attempt} attempts')
+				raise
+
 if __name__ == '__main__':
 	with open('keys.json') as f:
 		keys = json.load(f)