|
|
@@ -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)
|