Last active
May 2, 2020 12:30
-
-
Save TerryE/b6cd9fe2ca0ef8d7f6c1606832e45b69 to your computer and use it in GitHub Desktop.
Python script to download daily OVO smart meter usage
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
#!/usr/bin/env python | |
# This requires Python 2.7. This will not work with Python 3 | |
# Thanks to PaulW for the idea. In this case it was a matter of using | |
# the Ff Inspector Netwroks analyser to log the interactive query with | |
# "Persistent Logs" enabled, dumping the HAR to to pick out the key | |
# queries and with a bit of trial and error to refine them. | |
# | |
# I run this daily as a cron job. | |
from time import sleep | |
from requests import Request, Session | |
from datetime import datetime, time, timedelta | |
import json | |
import sys | |
import pprint | |
USERNAME = 'name@mail.box' | |
PASSWORD = r'''password''' | |
def pp(a): | |
pprint.PrettyPrinter(indent=2).pprint(a) | |
class OVOreadings: | |
def __init__(self, user, pwd): | |
self.MYOVO = 'my.ovoenergy.com' | |
self.PAYM = 'smartpaym.ovoenergy.com' | |
self.session = Session() | |
self.session.headers.update({ | |
'User-Agent' : 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) ' \ | |
+ 'Gecko/20100101 Firefox/62.0', | |
'Accept' : 'application/json,text/html', | |
'Accept-Encoding' : 'gzip, deflate, br', | |
'Accept-Language' : 'en-GB,en;q=0.5', | |
'DNT' : '1', | |
'Host' : self.MYOVO, | |
'Connection' : 'keep-alive' | |
}) | |
resp = self.session.get('https://%s/login' % self.MYOVO) | |
resp = self.session.post( | |
'https://%s/api/v2/auth/login' % self.MYOVO, | |
json = {'username' : user, 'password' : pwd, 'rememberMe' : True} | |
) | |
sleep(1) | |
resp = self.session.get('https://%s/api/customer-and-account-ids' % self.PAYM, | |
headers={'Host' : self.PAYM}) | |
self.account = json.loads(resp.content)['accountIds'][0] | |
def getReadings(self, date): | |
sleep(1) | |
resp = self.session.get( | |
'https://%s/api/energy-usage/half-hourly/%s?date=%s' % | |
(self.PAYM, self.account, date), | |
headers={'Host' : self.PAYM}) | |
data = json.loads(resp.content)['electricity']['data'] | |
value = {} | |
for v in data: | |
start = v['interval']['start'][11:16] | |
ndx = 2*int(start[0:2]) + (0 if start[3:5] == '00' else 1) | |
value[ndx] = v['consumption'] | |
return ["{:.3f}".format(value.get(i,0)) for i in range(0,48)] | |
def main(): | |
midnight = datetime.combine(datetime.today(), time.min) | |
yesterday = (midnight - timedelta(days=1)).strftime('%Y-%m-%d') | |
start = sys.argv[1] if len(sys.argv) > 1 else yesterday | |
end = sys.argv[2] if len(sys.argv) > 2 else start | |
start = datetime.strptime(start, '%Y-%m-%d').date() | |
end = datetime.strptime(end, '%Y-%m-%d').date() | |
heading = [(midnight+i*timedelta(minutes=30)).strftime('%H:%M') for i in range(0,48)] | |
print('Date,' + ','.join(heading)) | |
ovo = OVOreadings(USERNAME, PASSWORD) | |
for d in range(0, (end-start).days+1): | |
day = (start + d*timedelta(days=1)).strftime('%Y-%m-%d') | |
values = ovo.getReadings(day) | |
print(day + ',' + ','.join(values)) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment