Ver código fonte

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 meses atrás
pai
commit
aee65dff74
1 arquivos alterados com 31 adições e 5 exclusões
  1. 31 5
      main.py

+ 31 - 5
main.py

@@ -11,6 +11,7 @@
 
 import pyemvue
 import json
+import time
 
 from pyemvue.enums import Scale, Unit
 from pyemvue import PyEmVue
@@ -20,6 +21,7 @@ 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
 
 # Get & display minutely data for all devices.
 def allUsageOverTime(vue: PyEmVue):
@@ -38,11 +40,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 +57,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:
+				print(
+					f'Attempt {attempt} for channel {channel.name}',
+					f'from {start_time} to {end_time}',
+					f'failed:', e)
+				time.sleep(5)
+			else:
+				print(f'Failed after {attempt} attempts')
+				raise
+
 if __name__ == '__main__':
 	with open('keys.json') as f:
 		keys = json.load(f)