annotate graph.py @ 13:3f22fa1f32d5

Twiddle with start/end passing, add option for overriding local time zone.
author Daniel O'Connor <darius@dons.net.au>
date Fri, 22 Dec 2017 16:30:45 +0100
parents 2b115732f4bc
children aa18210c2703
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
1 #!/usr/bin/env python
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
2
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
3 import argparse
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
4 import datetime
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
5 import dateutil
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
6 import exceptions
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
7 import matplotlib
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
8 import matplotlib.dates
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
9 import numpy
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
10 import os
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
11 import requests
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
12 import sqlite3
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
13 import tzlocal
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
14
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
15 class Column(object):
8
30e7adf283ca Add depth of discharge annotation when plotting state_of_charge
Daniel O'Connor <darius@dons.net.au>
parents: 4
diff changeset
16 def __init__(self, rowname, title, table, units, limits = (None, None), conv = None, annofn = None):
4
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
17 self.rowname = rowname
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
18 self.title = title
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
19 self.table = table
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
20 self.units = units
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
21 self.limits = limits
8
30e7adf283ca Add depth of discharge annotation when plotting state_of_charge
Daniel O'Connor <darius@dons.net.au>
parents: 4
diff changeset
22 self.conv = conv
30e7adf283ca Add depth of discharge annotation when plotting state_of_charge
Daniel O'Connor <darius@dons.net.au>
parents: 4
diff changeset
23 self.annofn = annofn
4
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
24
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
25 columns = [
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
26 Column('main_voltage', 'Battery Voltage', 'eprolog', 'Vdc'),
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
27 Column('aux_voltage', 'Aux Voltage', 'eprolog', 'Vdc'),
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
28 Column('battery_curr', 'Battery Current', 'eprolog', 'A'),
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
29 Column('amp_hours', 'Battery Amp Hours', 'eprolog', 'Ah'),
8
30e7adf283ca Add depth of discharge annotation when plotting state_of_charge
Daniel O'Connor <darius@dons.net.au>
parents: 4
diff changeset
30 Column('state_of_charge', 'State of Charge', 'eprolog', '%', (0, 100), annofn = lambda xdata, ydata: 'DoD: %.1f' % (100 - ydata.min())),
4
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
31 Column('time_remaining', 'Time Remaining', 'eprolog', 'min'),
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
32 Column('battery_temp', 'Battery Temperature', 'eprolog', 'C'),
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
33
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
34 Column('ac_act_power', 'Active Power', 'giantlog', 'W'),
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
35 Column('ac_app_power', 'Apparent Power', 'giantlog', 'W'),
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
36 Column('ac_frequency', 'AC Frequency', 'giantlog', 'Hz'),
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
37 Column('ac_volts', 'AC Voltage', 'giantlog', 'Vac'),
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
38 Column('batt_chr_curr', 'Discharge Current', 'giantlog', 'A'),
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
39 Column('batt_dis_curr', 'Charge Current', 'giantlog', 'A'),
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
40 Column('battery_cap', 'Battery Capacity', 'giantlog', '%', (0, 100)),
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
41 Column('battery_volts', 'Battery Voltage', 'giantlog', 'Vdc'),
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
42 Column('grid_frequency', 'Grid Frequency', 'giantlog', 'Hz'),
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
43 Column('grid_volts', 'Grid Voltage', 'giantlog', 'Vac'),
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
44 Column('hs_temperature', 'HS Temperature', 'giantlog', 'C'),
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
45 Column('load_pct', 'Load', 'giantlog', '%', (0, 100)),
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
46 ]
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
47
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
48 def valid_date(s):
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
49 try:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
50 return datetime.datetime.strptime(s, "%Y-%m-%d")
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
51 except ValueError:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
52 raise argparse.ArgumentTypeError("Not a valid date: '{0}'.".format(s))
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
53
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
54 def main():
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
55 parser = argparse.ArgumentParser()
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
56 parser.add_argument('-f', '--filename', help = 'Path to database', type = str, required = True)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
57 parser.add_argument('-g', '--graphfn', help = 'File to write graph to', type = str)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
58 parser.add_argument('-d', '--days', help = 'Days ago to graph', type = int)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
59 parser.add_argument('-s', '--start', help = 'Start date for graph (YYYY-MM-DD)', type = valid_date)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
60 parser.add_argument('-e', '--end', help = 'End date for graph (YYYY-MM-DD)', type = valid_date)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
61 parser.add_argument('-c', '--column', help = 'Column to plot (can be specified multiple times)', type = str, action = 'append')
13
3f22fa1f32d5 Twiddle with start/end passing, add option for overriding local time zone.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
62 parser.add_argument('-z', '--timezone', help = 'Timezone to operate in in (Oslon format) default: localtime)', type = str)
4
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
63
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
64 args = parser.parse_args()
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
65
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
66 if args.days is not None and args.days < 0:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
67 parser.error('days must be non-negative')
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
68
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
69 # Can specify..
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
70 # Start and end
11
e1bec6dfd524 Improve start/end/days handling
Daniel O'Connor <darius@dons.net.au>
parents: 10
diff changeset
71 # Start and days or Start
e1bec6dfd524 Improve start/end/days handling
Daniel O'Connor <darius@dons.net.au>
parents: 10
diff changeset
72 # End and days or End
4
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
73 # Nothing
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
74 # Want to end up with a start & end
11
e1bec6dfd524 Improve start/end/days handling
Daniel O'Connor <darius@dons.net.au>
parents: 10
diff changeset
75 selector = [args.start is not None, args.end is not None, args.days is not None]
e1bec6dfd524 Improve start/end/days handling
Daniel O'Connor <darius@dons.net.au>
parents: 10
diff changeset
76 if selector == [True, True, False]:
4
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
77 pass
11
e1bec6dfd524 Improve start/end/days handling
Daniel O'Connor <darius@dons.net.au>
parents: 10
diff changeset
78 elif selector == [True, False, True] or selector == [True, False, False]:
e1bec6dfd524 Improve start/end/days handling
Daniel O'Connor <darius@dons.net.au>
parents: 10
diff changeset
79 if args.days == None:
e1bec6dfd524 Improve start/end/days handling
Daniel O'Connor <darius@dons.net.au>
parents: 10
diff changeset
80 args.days = 1
4
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
81 args.end = args.start + datetime.timedelta(days = args.days)
11
e1bec6dfd524 Improve start/end/days handling
Daniel O'Connor <darius@dons.net.au>
parents: 10
diff changeset
82 elif selector == [False, True, True] or selector == [False, True, False]:
e1bec6dfd524 Improve start/end/days handling
Daniel O'Connor <darius@dons.net.au>
parents: 10
diff changeset
83 if args.days == None:
e1bec6dfd524 Improve start/end/days handling
Daniel O'Connor <darius@dons.net.au>
parents: 10
diff changeset
84 args.days = 1
4
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
85 args.start = args.end - datetime.timedelta(days = args.days)
11
e1bec6dfd524 Improve start/end/days handling
Daniel O'Connor <darius@dons.net.au>
parents: 10
diff changeset
86 elif selector == [False, False, True]:
4
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
87 end = datetime.date.today()
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
88 end = datetime.datetime(start.year, start.month, start.day)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
89 args.start = args.end - datetime.timedelta(days = args.days)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
90 else:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
91 parser.error('can\'t specify days, start and end simultaneously')
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
92
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
93 if args.start >= args.end:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
94 parser.error('Start must be before end')
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
95
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
96 cols = args.column
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
97 if cols == None:
10
3f5b617b4715 Change default columns to be more useful
Daniel O'Connor <darius@dons.net.au>
parents: 9
diff changeset
98 cols = ['state_of_charge', 'load_pct', 'main_voltage', 'aux_voltage']
4
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
99
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
100 dbh = sqlite3.connect(args.filename, detect_types = sqlite3.PARSE_DECLTYPES)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
101 cur = dbh.cursor()
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
102
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
103 # Get local timezone name and convert start/end to it
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
104 # Why is this so hard...
13
3f22fa1f32d5 Twiddle with start/end passing, add option for overriding local time zone.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
105 if args.timezone is None:
3f22fa1f32d5 Twiddle with start/end passing, add option for overriding local time zone.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
106 args.timezone = tzlocal.get_localzone().zone
3f22fa1f32d5 Twiddle with start/end passing, add option for overriding local time zone.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
107
3f22fa1f32d5 Twiddle with start/end passing, add option for overriding local time zone.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
108 lt = dateutil.tz.gettz(args.timezone)
3f22fa1f32d5 Twiddle with start/end passing, add option for overriding local time zone.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
109 if lt == None:
3f22fa1f32d5 Twiddle with start/end passing, add option for overriding local time zone.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
110 parser.error('Unknown timezone')
3f22fa1f32d5 Twiddle with start/end passing, add option for overriding local time zone.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
111
4
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
112 utc = dateutil.tz.gettz('UTC')
13
3f22fa1f32d5 Twiddle with start/end passing, add option for overriding local time zone.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
113 matplotlib.rcParams['timezone'] = args.timezone
4
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
114
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
115 if args.start.tzinfo == None:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
116 args.start = args.start.replace(tzinfo = lt)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
117 if args.end.tzinfo == None:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
118 args.end = args.end.replace(tzinfo = lt)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
119 startlt = args.start
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
120 endlt = args.end
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
121 args.start = args.start.astimezone(utc)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
122 args.end = args.end.astimezone(utc)
13
3f22fa1f32d5 Twiddle with start/end passing, add option for overriding local time zone.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
123 graph(args.graphfn, cur, cols, args.start, args.end, lt, utc)
4
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
124
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
125 def graph(fname, cur, _cols, start, end, lt, utc):
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
126 import numpy
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
127 import matplotlib
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
128 import matplotlib.dates
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
129
13
3f22fa1f32d5 Twiddle with start/end passing, add option for overriding local time zone.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
130 startepoch = int(start.strftime('%s'))
3f22fa1f32d5 Twiddle with start/end passing, add option for overriding local time zone.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
131 endepoch = int(end.strftime('%s'))
4
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
132
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
133 colourlist = ['b','g','r','c','m','y','k']
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
134
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
135 cols = []
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
136
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
137 yaxisunits1 = None
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
138 yaxisunits2 = None
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
139 ax1lines = []
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
140 ax2lines = []
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
141 colouridx = 0
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
142 for col in _cols:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
143 # Check the column exists
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
144 for c in columns:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
145 if col == c.rowname:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
146 cols.append(c)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
147 break
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
148 else:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
149 raise exceptions.Exception('Unknown column name ' + c)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
150
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
151 # Work out what axes we are using
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
152 if yaxisunits1 == None:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
153 yaxisunits1 = c.units
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
154 if yaxisunits2 == None:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
155 if c.units != yaxisunits1:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
156 yaxisunits2 = c.units
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
157 else:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
158 if c.units != yaxisunits1 and c.units != yaxisunits2:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
159 raise exceptions.Exception('Asked to graph >2 different units')
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
160
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
161 for c in cols:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
162 # Get the data
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
163 cur.execute('SELECT tstamp, ' + c.rowname + ' FROM ' + c.table + ' WHERE tstamp > ? AND tstamp < ? ORDER BY tstamp',
13
3f22fa1f32d5 Twiddle with start/end passing, add option for overriding local time zone.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
164 (startepoch, endepoch))
4
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
165 ary = numpy.array(cur.fetchall())
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
166 if ary.shape[0] == 0:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
167 print('No data for ' + c.rowname)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
168 return
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
169
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
170 # Create TZ naive from POSIX stamp, then convert to TZ aware UTC then adjust to local time
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
171 c.xdata = map(lambda f: datetime.datetime.fromtimestamp(f).replace(tzinfo = utc).astimezone(lt), ary[:,0])
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
172 c.ydata = ary[:,1]
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
173 if c.conv != None:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
174 c.ydata = map(c.conv, c.ydata)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
175
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
176 scale_min, scale_max = c.limits
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
177
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
178 # DoD?
8
30e7adf283ca Add depth of discharge annotation when plotting state_of_charge
Daniel O'Connor <darius@dons.net.au>
parents: 4
diff changeset
179 if c.annofn != None:
30e7adf283ca Add depth of discharge annotation when plotting state_of_charge
Daniel O'Connor <darius@dons.net.au>
parents: 4
diff changeset
180 c.annotation = c.annofn(c.xdata, c.ydata)
30e7adf283ca Add depth of discharge annotation when plotting state_of_charge
Daniel O'Connor <darius@dons.net.au>
parents: 4
diff changeset
181 else:
30e7adf283ca Add depth of discharge annotation when plotting state_of_charge
Daniel O'Connor <darius@dons.net.au>
parents: 4
diff changeset
182 c.annotation = None
4
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
183
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
184 # Work out which axis to plot on
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
185 if c.units == yaxisunits1:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
186 ax = ax1lines
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
187 else:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
188 ax = ax2lines
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
189 c.colour = colourlist[colouridx]
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
190 colouridx += 1
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
191 ax.append(c)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
192
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
193 # Load the right backend for display or save
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
194 if fname == None:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
195 import matplotlib.pylab
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
196 fig = matplotlib.pylab.figure()
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
197 else:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
198 import matplotlib.backends.backend_agg
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
199 fig = matplotlib.figure.Figure(figsize = (12, 6), dpi = 75)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
200
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
201 # Do the plot
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
202 ax1 = fig.add_subplot(111)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
203 ax1.set_ylabel(yaxisunits1)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
204
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
205 annotations = []
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
206 for line in ax1lines:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
207 ax1.plot(line.xdata, line.ydata, label = line.title, color = line.colour)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
208 if line.limits[0] != None or line.limits[1] != None:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
209 ax1.set_ylim(line.limits[0], line.limits[1])
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
210 if line.annotation != None:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
211 annotations.append(line.annotation)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
212 ax1.legend(loc = 'upper left')
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
213
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
214 if len(ax2lines) > 0:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
215 ax2 = ax1.twinx()
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
216 ax2.set_ylabel(yaxisunits2)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
217
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
218 for line in ax2lines:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
219 ax2.plot(line.xdata, line.ydata, label = line.title, color = line.colour)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
220 if line.limits[0] != None or line.limits[1] != None:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
221 ax2.set_ylim(line.limits[0], line.limits[1])
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
222 if line.annotation != None:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
223 annotations.append(line.annotation)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
224
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
225 ax2.legend(loc = 'upper right')
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
226
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
227 if len(annotations) > 0:
9
899bc9c22787 Tweak annotation to be out of the way
Daniel O'Connor <darius@dons.net.au>
parents: 8
diff changeset
228 ax1.text(0.02, 0.5, reduce(lambda a, b: a + '\n' + b, annotations),
899bc9c22787 Tweak annotation to be out of the way
Daniel O'Connor <darius@dons.net.au>
parents: 8
diff changeset
229 transform = ax1.transAxes, bbox = dict(facecolor = 'blue', alpha = 0.5),
4
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
230 ha = 'left', va = 'top')
13
3f22fa1f32d5 Twiddle with start/end passing, add option for overriding local time zone.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
231 ndays = int(max(1, round(((end - start).total_seconds()) / 86400)))
4
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
232 for ax in fig.get_axes():
13
3f22fa1f32d5 Twiddle with start/end passing, add option for overriding local time zone.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
233 if ndays > 1:
3f22fa1f32d5 Twiddle with start/end passing, add option for overriding local time zone.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
234 ax.set_title('%s to %s' % (start.strftime('%Y-%m-%d'), end.strftime('%Y-%m-%d')))
4
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
235 else:
13
3f22fa1f32d5 Twiddle with start/end passing, add option for overriding local time zone.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
236 ax.set_title('%s' % (start.strftime('%Y-%m-%d')))
3f22fa1f32d5 Twiddle with start/end passing, add option for overriding local time zone.
Daniel O'Connor <darius@dons.net.au>
parents: 12
diff changeset
237 ax.set_xlim([start, end])
4
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
238 ax.format_xdata = lambda d: matplotlib.dates.num2date(d).strftime('%d %b %H:%M')
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
239 ax.xaxis.grid(True)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
240 ax.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%d %b\n%H:%M'))
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
241 ax.xaxis.set_major_locator(matplotlib.dates.HourLocator(interval = 2 * ndays))
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
242 ax.xaxis.set_minor_locator(matplotlib.dates.MinuteLocator(interval = 5 * ndays))
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
243 for label in ax.get_xticklabels():
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
244 label.set_ha('center')
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
245 label.set_rotation(90)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
246
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
247 # Fudge margins to give more graph and less space
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
248 fig.subplots_adjust(left = 0.10, right = 0.88, top = 0.95, bottom = 0.15)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
249 if fname == None:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
250 matplotlib.pyplot.show()
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
251 else:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
252 canvas = matplotlib.backends.backend_agg.FigureCanvasAgg(fig) # Sets canvas in fig too
12
2b115732f4bc Fix graph saving
Daniel O'Connor <darius@dons.net.au>
parents: 11
diff changeset
253 fig.savefig(startdt.strftime(fname))
4
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
254
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
255 def updatedb(cur, data):
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
256 mkdb(cur)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
257 for d in data['reads']['data']:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
258 ts = datetime.datetime.strptime(d['t_stamp'], '%Y-%m-%dT%H:%M:%SZ')
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
259 # Note we rename *energy* to *power* here to match what it actually means
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
260 vals = [ts, d['battery_charge'], d['battery_energy'], d['energy_consumed'], d['energy_expected'], d['energy_exported'], d['energy_generated'],
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
261 d['energy_imported'], d['estimated_savings'], d['pv_forecast'], d['pv_generation']['battery_energy'],
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
262 d['pv_generation']['grid_energy'], d['pv_generation']['site_energy'], d['site_consumption']['battery_energy'],
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
263 d['site_consumption']['grid_energy'], d['site_consumption']['pv_energy']]
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
264 skip = True
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
265 for v in vals[1:]:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
266 if v != None:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
267 skip = False
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
268 break
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
269 if skip:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
270 print('Skipping empty record at ' + str(ts))
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
271 continue
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
272 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)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
273
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
274 def gettoken(username, password):
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
275 authblob = json.encoder.JSONEncoder().encode({'email' : username, 'password' : password})
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
276 reply = requests.request('POST', loginurl, data = authblob, headers = {'Content-Type' : 'application/json'})
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
277 if reply.status_code != 200:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
278 return None
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
279 return json.decoder.JSONDecoder().decode(reply.content)['access_token']
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
280
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
281 def getdata(token, startdate, enddate):
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
282 #print('getting ' + startdate.strftime('%Y-%m-%d'))
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
283 reply = requests.request('GET', dataurl, params = {
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
284 'startDate' : startdate.strftime('%Y-%m-%d'),
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
285 'endDate' : enddate.strftime('%Y-%m-%d'),
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
286 'granularity' : 'Minute',
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
287 'metrics' : 'read',
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
288 'units' : 'W',
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
289 }, headers = { 'Authorization' : 'Bearer ' + token})
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
290
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
291 if reply.status_code != 200:
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
292 return None
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
293
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
294 return json.decoder.JSONDecoder().decode(reply.content)
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
295
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
296 def logout(token):
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
297 reply = requests.request('GET', logouturl, headers = { 'Authorization' : 'Bearer ' + token})
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
298 return reply.status_code == 200
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
299
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
300 if __name__ == '__main__':
a7e9775b33f6 Add graph script based on AGL code (but better)
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
301 main()