Mercurial > ~darius > hgwebdir.cgi > vanlogger
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 |
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 | 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() |