annotate agl.py @ 19:1d08f777533f default tip

Add installid parameter instead of hard coding it into a URL.
author Daniel O'Connor <darius@dons.net.au>
date Tue, 03 Jul 2018 13:26:28 +0930
parents 156ab071a9de
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
1 #!/usr/bin/env python
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
2
2
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
3 import argparse
0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
4 import ConfigParser
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
5 import datetime
1
6e3ca5bfda04 Improve plotting/timezone stuff.
Daniel O'Connor <darius@dons.net.au>
parents: 0
diff changeset
6 import dateutil
0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
7 import exceptions
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
8 import json
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
9 import os
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
10 import requests
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
11 import sqlite3
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
12 import sys
2
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
13 import tzlocal
0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
14
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
15 loginurl = 'https://command.aglsolar.com.au/api/v2/Account/LoginUser'
19
1d08f777533f Add installid parameter instead of hard coding it into a URL.
Daniel O'Connor <darius@dons.net.au>
parents: 18
diff changeset
16 dataurl = 'https://command.aglsolar.com.au/api/v2/graph/'
0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
17 # ?endDate=2017-08-23&granularity=Minute&metrics=read&startDate=2017-08-23&units=W'
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
18 logouturl = 'https://command.aglsolar.com.au/api/v2/Account/Logout'
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
19
2
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
20 def valid_date(s):
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
21 try:
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
22 return datetime.datetime.strptime(s, "%Y-%m-%d")
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
23 except ValueError:
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
24 raise argparse.ArgumentTypeError("Not a valid date: '{0}'.".format(s))
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
25
0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
26 def main():
2
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
27 parser = argparse.ArgumentParser()
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
28 parser.add_argument('-u', '--update', help = 'Update data', action="store_true")
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
29 parser.add_argument('-g', '--graph', help = 'Produce graph', action="store_true")
13
988e511a5f29 Run strftime on filename.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
30 parser.add_argument('-f', '--filename', help = 'Filename to save graph as (uses strftime on start)', type = str)
14
db4951d2d303 Add option to graph N days ago easily.
Daniel O'Connor <darius@dons.net.au>
parents: 13
diff changeset
31 parser.add_argument('-d', '--days', help = 'Days ago to graph', type = int)
2
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
32 parser.add_argument('-s', '--start', help = 'Start date for graph (YYYY-MM-DD)', type = valid_date)
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
33 parser.add_argument('-e', '--end', help = 'End date for graph (YYYY-MM-DD)', type = valid_date)
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
34
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
35 args = parser.parse_args()
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
36
0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
37 conf = ConfigParser.ConfigParser()
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
38 confname = os.environ['HOME'] + '/.agl.ini'
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
39 conf.read(confname)
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
40 username = conf.get('DEFAULT', 'username')
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
41 password = conf.get('DEFAULT', 'password')
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
42 dbfn = conf.get('DEFAULT', 'db')
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
43
2
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
44 if not args.update and not args.graph:
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
45 parser.error('Nothing to do')
0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
46
15
7fd3dc0516f8 Do some option sanity checking.
Daniel O'Connor <darius@dons.net.au>
parents: 14
diff changeset
47 if args.days is not None and args.days < 0:
7fd3dc0516f8 Do some option sanity checking.
Daniel O'Connor <darius@dons.net.au>
parents: 14
diff changeset
48 parser.error('days must be non-negative')
7fd3dc0516f8 Do some option sanity checking.
Daniel O'Connor <darius@dons.net.au>
parents: 14
diff changeset
49
2
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
50 start = args.start
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
51 if start is None:
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
52 start = datetime.date.today()
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
53 start = datetime.datetime(start.year, start.month, start.day)
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
54
14
db4951d2d303 Add option to graph N days ago easily.
Daniel O'Connor <darius@dons.net.au>
parents: 13
diff changeset
55 if args.days is not None:
db4951d2d303 Add option to graph N days ago easily.
Daniel O'Connor <darius@dons.net.au>
parents: 13
diff changeset
56 start -= datetime.timedelta(days = args.days)
db4951d2d303 Add option to graph N days ago easily.
Daniel O'Connor <darius@dons.net.au>
parents: 13
diff changeset
57
2
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
58 end = args.end
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
59 if end is None:
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
60 end = start + datetime.timedelta(days = 1)
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
61 end = datetime.datetime(end.year, end.month, end.day)
14
db4951d2d303 Add option to graph N days ago easily.
Daniel O'Connor <darius@dons.net.au>
parents: 13
diff changeset
62
15
7fd3dc0516f8 Do some option sanity checking.
Daniel O'Connor <darius@dons.net.au>
parents: 14
diff changeset
63 if start >= end:
7fd3dc0516f8 Do some option sanity checking.
Daniel O'Connor <darius@dons.net.au>
parents: 14
diff changeset
64 parser.error('Start must be before end')
7fd3dc0516f8 Do some option sanity checking.
Daniel O'Connor <darius@dons.net.au>
parents: 14
diff changeset
65
0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
66 dbh = sqlite3.connect(dbfn, detect_types = sqlite3.PARSE_DECLTYPES)
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
67 cur = dbh.cursor()
2
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
68 if args.update:
19
1d08f777533f Add installid parameter instead of hard coding it into a URL.
Daniel O'Connor <darius@dons.net.au>
parents: 18
diff changeset
69 installid = conf.get('DEFAULT', 'installid')
2
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
70 date = start
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
71 while date < end:
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
72 if conf.has_option('DEFAULT', 'token'):
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
73 token = conf.get('DEFAULT', 'token')
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
74 else:
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
75 token = gettoken(username, password)
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
76 conf.set('DEFAULT', 'token', token)
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
77 conf.write(file(confname, 'w'))
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
78
19
1d08f777533f Add installid parameter instead of hard coding it into a URL.
Daniel O'Connor <darius@dons.net.au>
parents: 18
diff changeset
79 data = getdata(token, installid, date, date)
2
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
80 if data == None:
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
81 #print('Getting new token')
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
82 token = gettoken(username, password)
19
1d08f777533f Add installid parameter instead of hard coding it into a URL.
Daniel O'Connor <darius@dons.net.au>
parents: 18
diff changeset
83 data = getdata(token, installid, date, date)
2
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
84 if data == None:
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
85 print('Unable to fetch data')
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
86 updatedb(cur, data)
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
87 dbh.commit()
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
88 date += datetime.timedelta(days = 1)
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
89
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
90 if args.graph:
13
988e511a5f29 Run strftime on filename.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
91 graph(args.filename, cur,
988e511a5f29 Run strftime on filename.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
92 ['battery_charge', 'battery_power', 'power_imported', 'power_exported', 'power_consumed', 'power_generated'],
988e511a5f29 Run strftime on filename.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
93 start, end)
0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
94
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
95 def mkdb(cur):
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
96 cur.execute('''
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
97 CREATE TABLE IF NOT EXISTS agl (
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
98 t_stamp TIMESTAMP PRIMARY KEY,
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
99 battery_charge NUMBER,
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
100 battery_power NUMBER,
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
101 power_consumed NUMBER,
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
102 power_expected NUMBER,
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
103 power_exported NUMBER,
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
104 power_generated NUMBER,
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
105 power_imported NUMBER,
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
106 estimated_savings NUMBER,
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
107 pv_forecast NUMBER,
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
108 pv_gen_battery NUMBER,
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
109 pv_gen_grid NUMBER,
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
110 pv_gen_site NUMBER,
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
111 site_cons_battery NUMBER,
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
112 site_cons_grid NUMBER,
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
113 site_cons_pv NUMBER
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
114 )''')
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
115
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
116 units = {
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
117 'battery_charge' : '%',
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
118 'battery_power' : 'Watt',
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
119 'power_consumed' : 'Watt',
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
120 'power_expected' : 'Watt',
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
121 'power_exported' : 'Watt',
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
122 'power_generated' : 'Watt',
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
123 'power_imported' : 'Watt',
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
124 'estimated_savings' : '$',
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
125 'pv_forecast' : 'Watt',
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
126 'pv_gen_battery' : 'Watt',
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
127 'pv_gen_grid' : 'Watt',
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
128 'pv_gen_site' : 'Watt',
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
129 'site_cons_battery' : 'Watt',
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
130 'site_cons_grid' : 'Watt',
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
131 'site_cons_pv' : 'Watt'
2
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
132 }
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
133
5
b42baa411817 Display battery_power (which seems to be in milliwatts..?)
Daniel O'Connor <darius@dons.net.au>
parents: 4
diff changeset
134 convs = {
8
22d31cee19b1 Misc tidyup, no functional change
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
135 'battery_power' : lambda a: a / 1000.0,
22d31cee19b1 Misc tidyup, no functional change
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
136 }
22d31cee19b1 Misc tidyup, no functional change
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
137
22d31cee19b1 Misc tidyup, no functional change
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
138 scale_limits = {
22d31cee19b1 Misc tidyup, no functional change
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
139 'battery_charge' : (0, 100),
5
b42baa411817 Display battery_power (which seems to be in milliwatts..?)
Daniel O'Connor <darius@dons.net.au>
parents: 4
diff changeset
140 }
b42baa411817 Display battery_power (which seems to be in milliwatts..?)
Daniel O'Connor <darius@dons.net.au>
parents: 4
diff changeset
141
10
70cc1e874157 Print import/export tarrifs
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
142 tarrifs = {
70cc1e874157 Print import/export tarrifs
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
143 'power_exported' : 0.163,
70cc1e874157 Print import/export tarrifs
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
144 'power_imported' : 0.380,
11
9fac3371e9ad Print consumption and generation, tTwiddle text box, remove debugging.
Daniel O'Connor <darius@dons.net.au>
parents: 10
diff changeset
145 'power_generated' : 0.163,
9fac3371e9ad Print consumption and generation, tTwiddle text box, remove debugging.
Daniel O'Connor <darius@dons.net.au>
parents: 10
diff changeset
146 'power_consumed' : 0.380,
10
70cc1e874157 Print import/export tarrifs
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
147 }
70cc1e874157 Print import/export tarrifs
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
148
2
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
149 names = {
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
150 'battery_charge' : 'Battery Charge',
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
151 'battery_power' : 'Battery Power',
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
152 'power_consumed' : 'Power Consumed',
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
153 'power_expected' : 'Power Expected',
6
2e50426c946f Use correct name for power_exported
Daniel O'Connor <darius@dons.net.au>
parents: 5
diff changeset
154 'power_exported' : 'Power Exported',
2
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
155 'power_generated' : 'Power Generated',
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
156 'power_imported' : 'Power Imported',
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
157 'estimated_savings' : 'Estimated Savings',
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
158 'pv_forecast' : 'PV Forecast',
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
159 'pv_gen_battery' : 'PV Generation Battery',
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
160 'pv_gen_grid' : 'PV Generation Grid',
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
161 'pv_gen_site' : 'PV Generation Site',
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
162 'site_cons_battery' : 'Site Consumption Batter',
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
163 'site_cons_grid' : 'Site Consumption Grid',
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
164 'site_cons_pv' : 'Site Consumption PV'
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
165 }
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
166
4
deb3adc4e086 Add graph saving option.
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
167 def graph(fname, cur, cols, start, end):
0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
168 import numpy
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
169 import matplotlib
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
170 import matplotlib.dates
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
171
1
6e3ca5bfda04 Improve plotting/timezone stuff.
Daniel O'Connor <darius@dons.net.au>
parents: 0
diff changeset
172 colourlist = ['b','g','r','c','m','y','k']
0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
173
1
6e3ca5bfda04 Improve plotting/timezone stuff.
Daniel O'Connor <darius@dons.net.au>
parents: 0
diff changeset
174 # Work out what axes we are using
0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
175 yaxisunits1 = None
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
176 yaxisunits2 = None
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
177 ax1lines = []
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
178 ax2lines = []
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
179 colouridx = 0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
180 for col in cols:
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
181 unit = units[col]
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
182 if yaxisunits1 == None:
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
183 yaxisunits1 = unit
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
184 if yaxisunits2 == None:
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
185 if unit != yaxisunits1:
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
186 yaxisunits2 = unit
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
187 else:
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
188 if unit != yaxisunits1 and unit != yaxisunits2:
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
189 raise exceptions.Exception('Asked to graph >2 different units')
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
190
2
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
191 ltname = tzlocal.get_localzone().zone # Why is this so hard..
1
6e3ca5bfda04 Improve plotting/timezone stuff.
Daniel O'Connor <darius@dons.net.au>
parents: 0
diff changeset
192 lt = dateutil.tz.gettz(ltname)
6e3ca5bfda04 Improve plotting/timezone stuff.
Daniel O'Connor <darius@dons.net.au>
parents: 0
diff changeset
193 utc = dateutil.tz.gettz('UTC')
6e3ca5bfda04 Improve plotting/timezone stuff.
Daniel O'Connor <darius@dons.net.au>
parents: 0
diff changeset
194 matplotlib.rcParams['timezone'] = ltname
6e3ca5bfda04 Improve plotting/timezone stuff.
Daniel O'Connor <darius@dons.net.au>
parents: 0
diff changeset
195
6e3ca5bfda04 Improve plotting/timezone stuff.
Daniel O'Connor <darius@dons.net.au>
parents: 0
diff changeset
196 if start.tzinfo == None:
6e3ca5bfda04 Improve plotting/timezone stuff.
Daniel O'Connor <darius@dons.net.au>
parents: 0
diff changeset
197 start = start.replace(tzinfo = lt)
6e3ca5bfda04 Improve plotting/timezone stuff.
Daniel O'Connor <darius@dons.net.au>
parents: 0
diff changeset
198 if end.tzinfo == None:
6e3ca5bfda04 Improve plotting/timezone stuff.
Daniel O'Connor <darius@dons.net.au>
parents: 0
diff changeset
199 end = end.replace(tzinfo = lt)
13
988e511a5f29 Run strftime on filename.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
200 startlt = start
988e511a5f29 Run strftime on filename.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
201 endlt = end
1
6e3ca5bfda04 Improve plotting/timezone stuff.
Daniel O'Connor <darius@dons.net.au>
parents: 0
diff changeset
202 start = start.astimezone(utc)
6e3ca5bfda04 Improve plotting/timezone stuff.
Daniel O'Connor <darius@dons.net.au>
parents: 0
diff changeset
203 end = end.astimezone(utc)
6e3ca5bfda04 Improve plotting/timezone stuff.
Daniel O'Connor <darius@dons.net.au>
parents: 0
diff changeset
204
6e3ca5bfda04 Improve plotting/timezone stuff.
Daniel O'Connor <darius@dons.net.au>
parents: 0
diff changeset
205 # Actually get the data
6e3ca5bfda04 Improve plotting/timezone stuff.
Daniel O'Connor <darius@dons.net.au>
parents: 0
diff changeset
206 colstr = reduce(lambda a, b: a + ', ' + b, cols)
6e3ca5bfda04 Improve plotting/timezone stuff.
Daniel O'Connor <darius@dons.net.au>
parents: 0
diff changeset
207 # Data is stored as naive datetime's which are in UTC so convert the requested time here
6e3ca5bfda04 Improve plotting/timezone stuff.
Daniel O'Connor <darius@dons.net.au>
parents: 0
diff changeset
208 cur.execute('SELECT t_stamp, ' + colstr + ' FROM agl WHERE t_stamp > ? AND t_stamp < ? ORDER BY t_stamp',
0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
209 (start, end))
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
210 ary = numpy.array(cur.fetchall())
2
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
211 if ary.shape[0] == 0:
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
212 print('No data')
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
213 return
8
22d31cee19b1 Misc tidyup, no functional change
Daniel O'Connor <darius@dons.net.au>
parents: 7
diff changeset
214 # Convert TZ naive UTC to TZ aware UTC then adjust to local time
1
6e3ca5bfda04 Improve plotting/timezone stuff.
Daniel O'Connor <darius@dons.net.au>
parents: 0
diff changeset
215 xdata = map(lambda f: f.replace(tzinfo = utc).astimezone(lt), ary[:,0])
10
70cc1e874157 Print import/export tarrifs
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
216 xhours = matplotlib.dates.date2num(xdata) * 24
70cc1e874157 Print import/export tarrifs
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
217 xdeltas = xhours[1:] - xhours[0:-1]
17
227a2a524675 Annotate how much was saved if the data is plotted.
Daniel O'Connor <darius@dons.net.au>
parents: 16
diff changeset
218 calcd = {}
0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
219 for idx in range(len(cols)):
10
70cc1e874157 Print import/export tarrifs
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
220 col = cols[idx]
5
b42baa411817 Display battery_power (which seems to be in milliwatts..?)
Daniel O'Connor <darius@dons.net.au>
parents: 4
diff changeset
221 ydata = ary[:,idx + 1]
19
1d08f777533f Add installid parameter instead of hard coding it into a URL.
Daniel O'Connor <darius@dons.net.au>
parents: 18
diff changeset
222
1d08f777533f Add installid parameter instead of hard coding it into a URL.
Daniel O'Connor <darius@dons.net.au>
parents: 18
diff changeset
223 ydata = [0 if v is None else v for v in ydata]
10
70cc1e874157 Print import/export tarrifs
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
224 if col in convs:
19
1d08f777533f Add installid parameter instead of hard coding it into a URL.
Daniel O'Connor <darius@dons.net.au>
parents: 18
diff changeset
225 ydata = map(convs[col], ydata)
10
70cc1e874157 Print import/export tarrifs
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
226 if col in scale_limits:
70cc1e874157 Print import/export tarrifs
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
227 scale_min = scale_limits[col][0]
70cc1e874157 Print import/export tarrifs
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
228 scale_max = scale_limits[col][1]
9
e2807c99e107 Fix battery charge scale to 0-100.
Daniel O'Connor <darius@dons.net.au>
parents: 8
diff changeset
229 else:
e2807c99e107 Fix battery charge scale to 0-100.
Daniel O'Connor <darius@dons.net.au>
parents: 8
diff changeset
230 scale_min = None
e2807c99e107 Fix battery charge scale to 0-100.
Daniel O'Connor <darius@dons.net.au>
parents: 8
diff changeset
231 scale_max = None
e2807c99e107 Fix battery charge scale to 0-100.
Daniel O'Connor <darius@dons.net.au>
parents: 8
diff changeset
232
10
70cc1e874157 Print import/export tarrifs
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
233 if col in tarrifs:
17
227a2a524675 Annotate how much was saved if the data is plotted.
Daniel O'Connor <darius@dons.net.au>
parents: 16
diff changeset
234 calc = (ydata[1:] * xdeltas).sum() / 1000.0 * tarrifs[col]
227a2a524675 Annotate how much was saved if the data is plotted.
Daniel O'Connor <darius@dons.net.au>
parents: 16
diff changeset
235 annotation = '%s: $%.2f' % (names[col], calc)
227a2a524675 Annotate how much was saved if the data is plotted.
Daniel O'Connor <darius@dons.net.au>
parents: 16
diff changeset
236 calcd[col] = calc
10
70cc1e874157 Print import/export tarrifs
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
237 else:
70cc1e874157 Print import/export tarrifs
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
238 annotation = None
70cc1e874157 Print import/export tarrifs
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
239
70cc1e874157 Print import/export tarrifs
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
240 if units[col] == yaxisunits1:
9
e2807c99e107 Fix battery charge scale to 0-100.
Daniel O'Connor <darius@dons.net.au>
parents: 8
diff changeset
241 ax = ax1lines
0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
242 else:
9
e2807c99e107 Fix battery charge scale to 0-100.
Daniel O'Connor <darius@dons.net.au>
parents: 8
diff changeset
243 ax = ax2lines
10
70cc1e874157 Print import/export tarrifs
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
244 ax.append([xdata, ydata, names[col], colourlist[colouridx], scale_min, scale_max, annotation])
0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
245 colouridx += 1
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
246
4
deb3adc4e086 Add graph saving option.
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
247 if fname == None:
deb3adc4e086 Add graph saving option.
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
248 import matplotlib.pylab
deb3adc4e086 Add graph saving option.
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
249 fig = matplotlib.pylab.figure()
deb3adc4e086 Add graph saving option.
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
250 else:
deb3adc4e086 Add graph saving option.
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
251 import matplotlib.backends.backend_agg
16
201ad77bac40 Widen graph
Daniel O'Connor <darius@dons.net.au>
parents: 15
diff changeset
252 fig = matplotlib.figure.Figure(figsize = (12, 6), dpi = 75)
4
deb3adc4e086 Add graph saving option.
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
253
0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
254 ax1 = fig.add_subplot(111)
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
255 ax1.set_ylabel(yaxisunits1)
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
256
10
70cc1e874157 Print import/export tarrifs
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
257 annotations = []
0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
258 for line in ax1lines:
9
e2807c99e107 Fix battery charge scale to 0-100.
Daniel O'Connor <darius@dons.net.au>
parents: 8
diff changeset
259 ax1.plot(line[0], line[1], label = line[2], color = line[3])
e2807c99e107 Fix battery charge scale to 0-100.
Daniel O'Connor <darius@dons.net.au>
parents: 8
diff changeset
260 if line[4] != None and line[5] != None:
e2807c99e107 Fix battery charge scale to 0-100.
Daniel O'Connor <darius@dons.net.au>
parents: 8
diff changeset
261 ax1.set_ylim((line[4], line[5]))
10
70cc1e874157 Print import/export tarrifs
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
262 if line[6] != None:
70cc1e874157 Print import/export tarrifs
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
263 annotations.append(line[6])
0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
264 ax1.legend(loc = 'upper left')
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
265
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
266 if yaxisunits2 != None:
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
267 ax2 = ax1.twinx()
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
268 ax2.set_ylabel(yaxisunits2)
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
269
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
270 for line in ax2lines:
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
271 ax2.plot(line[0], line[1], label = line[2], color = line[3])
9
e2807c99e107 Fix battery charge scale to 0-100.
Daniel O'Connor <darius@dons.net.au>
parents: 8
diff changeset
272 if line[4] != None and line[5] != None:
e2807c99e107 Fix battery charge scale to 0-100.
Daniel O'Connor <darius@dons.net.au>
parents: 8
diff changeset
273 ax2.set_ylim(bottom = line[4], top = line[5])
10
70cc1e874157 Print import/export tarrifs
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
274 if line[6] != None:
70cc1e874157 Print import/export tarrifs
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
275 annotations.append(line[6])
70cc1e874157 Print import/export tarrifs
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
276
0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
277 ax2.legend(loc = 'upper right')
17
227a2a524675 Annotate how much was saved if the data is plotted.
Daniel O'Connor <darius@dons.net.au>
parents: 16
diff changeset
278 if all(map(lambda x: x in calcd, ('power_imported', 'power_exported', 'power_consumed', 'power_generated'))):
227a2a524675 Annotate how much was saved if the data is plotted.
Daniel O'Connor <darius@dons.net.au>
parents: 16
diff changeset
279 annotations.append('Saved: $%0.2f' % ((calcd['power_consumed'] - calcd['power_generated']) -
227a2a524675 Annotate how much was saved if the data is plotted.
Daniel O'Connor <darius@dons.net.au>
parents: 16
diff changeset
280 (calcd['power_imported'] - calcd['power_exported'])))
11
9fac3371e9ad Print consumption and generation, tTwiddle text box, remove debugging.
Daniel O'Connor <darius@dons.net.au>
parents: 10
diff changeset
281 ax1.text(0.02, 0.9, reduce(lambda a, b: a + '\n' + b, annotations),
9fac3371e9ad Print consumption and generation, tTwiddle text box, remove debugging.
Daniel O'Connor <darius@dons.net.au>
parents: 10
diff changeset
282 transform = ax1.transAxes, bbox = dict(facecolor = 'red', alpha = 0.5),
9fac3371e9ad Print consumption and generation, tTwiddle text box, remove debugging.
Daniel O'Connor <darius@dons.net.au>
parents: 10
diff changeset
283 ha = 'left', va = 'top')
2
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
284 ndays = int(max(1, round(((end - start).total_seconds()) / 86400)))
0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
285 for ax in fig.get_axes():
18
156ab071a9de Only print the start date if the duration is 1 day
Daniel O'Connor <darius@dons.net.au>
parents: 17
diff changeset
286 if (endlt - startlt).total_seconds() > 86400:
156ab071a9de Only print the start date if the duration is 1 day
Daniel O'Connor <darius@dons.net.au>
parents: 17
diff changeset
287 ax.set_title('%s to %s' % (startlt.strftime('%Y-%m-%d'), endlt.strftime('%Y-%m-%d')))
156ab071a9de Only print the start date if the duration is 1 day
Daniel O'Connor <darius@dons.net.au>
parents: 17
diff changeset
288 else:
156ab071a9de Only print the start date if the duration is 1 day
Daniel O'Connor <darius@dons.net.au>
parents: 17
diff changeset
289 ax.set_title('%s' % (startlt.strftime('%Y-%m-%d')))
1
6e3ca5bfda04 Improve plotting/timezone stuff.
Daniel O'Connor <darius@dons.net.au>
parents: 0
diff changeset
290 ax.set_xlim([start, end])
3
525a66486282 Fix mouse hover formatting.
Daniel O'Connor <darius@dons.net.au>
parents: 2
diff changeset
291 ax.format_xdata = lambda d: matplotlib.dates.num2date(d).strftime('%d %b %H:%M')
1
6e3ca5bfda04 Improve plotting/timezone stuff.
Daniel O'Connor <darius@dons.net.au>
parents: 0
diff changeset
292 ax.xaxis.grid(True)
6e3ca5bfda04 Improve plotting/timezone stuff.
Daniel O'Connor <darius@dons.net.au>
parents: 0
diff changeset
293 ax.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%d %b\n%H:%M'))
2
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
294 ax.xaxis.set_major_locator(matplotlib.dates.HourLocator(interval = 2 * ndays))
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
295 ax.xaxis.set_minor_locator(matplotlib.dates.MinuteLocator(interval = 5 * ndays))
0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
296 for label in ax.get_xticklabels():
1
6e3ca5bfda04 Improve plotting/timezone stuff.
Daniel O'Connor <darius@dons.net.au>
parents: 0
diff changeset
297 label.set_ha('center')
6e3ca5bfda04 Improve plotting/timezone stuff.
Daniel O'Connor <darius@dons.net.au>
parents: 0
diff changeset
298 label.set_rotation(90)
0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
299
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
300 # Fudge margins to give more graph and less space
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
301 fig.subplots_adjust(left = 0.10, right = 0.88, top = 0.95, bottom = 0.15)
4
deb3adc4e086 Add graph saving option.
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
302 if fname == None:
deb3adc4e086 Add graph saving option.
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
303 matplotlib.pyplot.show()
deb3adc4e086 Add graph saving option.
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
304 else:
deb3adc4e086 Add graph saving option.
Daniel O'Connor <darius@dons.net.au>
parents: 3
diff changeset
305 canvas = matplotlib.backends.backend_agg.FigureCanvasAgg(fig) # Sets canvas in fig too
13
988e511a5f29 Run strftime on filename.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
306 fig.savefig(startlt.strftime(fname))
0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
307
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
308 def updatedb(cur, data):
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
309 mkdb(cur)
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
310 for d in data['reads']['data']:
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
311 ts = datetime.datetime.strptime(d['t_stamp'], '%Y-%m-%dT%H:%M:%SZ')
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
312 # Note we rename *energy* to *power* here to match what it actually means
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
313 vals = [ts, d['battery_charge'], d['battery_energy'], d['energy_consumed'], d['energy_expected'], d['energy_exported'], d['energy_generated'],
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
314 d['energy_imported'], d['estimated_savings'], d['pv_forecast'], d['pv_generation']['battery_energy'],
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
315 d['pv_generation']['grid_energy'], d['pv_generation']['site_energy'], d['site_consumption']['battery_energy'],
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
316 d['site_consumption']['grid_energy'], d['site_consumption']['pv_energy']]
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
317 skip = True
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
318 for v in vals[1:]:
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
319 if v != None:
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
320 skip = False
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
321 break
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
322 if skip:
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
323 print('Skipping empty record at ' + str(ts))
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
324 continue
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
325 cur.execute('INSERT OR IGNORE INTO agl(t_stamp, battery_charge, battery_power, power_consumed, power_expected, power_exported, power_generated, power_imported, estimated_savings, pv_forecast, pv_gen_battery, pv_gen_grid, pv_gen_site, site_cons_battery, site_cons_grid, site_cons_pv) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', vals)
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
326
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
327 def gettoken(username, password):
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
328 authblob = json.encoder.JSONEncoder().encode({'email' : username, 'password' : password})
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
329 reply = requests.request('POST', loginurl, data = authblob, headers = {'Content-Type' : 'application/json'})
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
330 if reply.status_code != 200:
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
331 return None
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
332 return json.decoder.JSONDecoder().decode(reply.content)['access_token']
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
333
19
1d08f777533f Add installid parameter instead of hard coding it into a URL.
Daniel O'Connor <darius@dons.net.au>
parents: 18
diff changeset
334 def getdata(token, installid, startdate, enddate):
2
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
335 #print('getting ' + startdate.strftime('%Y-%m-%d'))
19
1d08f777533f Add installid parameter instead of hard coding it into a URL.
Daniel O'Connor <darius@dons.net.au>
parents: 18
diff changeset
336 reply = requests.request('GET', dataurl + installid, params = {
2
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
337 'startDate' : startdate.strftime('%Y-%m-%d'),
2b7fb26f9114 - Make an actual usable command line program.
Daniel O'Connor <darius@dons.net.au>
parents: 1
diff changeset
338 'endDate' : enddate.strftime('%Y-%m-%d'),
0
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
339 'granularity' : 'Minute',
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
340 'metrics' : 'read',
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
341 'units' : 'W',
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
342 }, headers = { 'Authorization' : 'Bearer ' + token})
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
343
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
344 if reply.status_code != 200:
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
345 return None
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
346
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
347 return json.decoder.JSONDecoder().decode(reply.content)
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
348
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
349 def logout(token):
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
350 reply = requests.request('GET', logouturl, headers = { 'Authorization' : 'Bearer ' + token})
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
351 return reply.status_code == 200
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
352
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
353 if __name__ == '__main__':
8d6ba11c1b76 Fetch & graphing code basically works.
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
354 main()