-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsqlite_access.py
More file actions
132 lines (110 loc) · 4.7 KB
/
sqlite_access.py
File metadata and controls
132 lines (110 loc) · 4.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
""" module for providing access to the brightness database, stored in sqlite3
"""
import sqlite3
import datetime
import logging
import json
import os
import pytz
from collections import deque
DB_FILE = os.path.join(os.path.dirname(__file__), 'brightness.db')
tz = pytz.timezone('Europe/Brussels')
def simplemovingaverage(period):
assert period == int(period) and period > 0, "Period must be an integer >0"
av = {'summ':0.0, 'n':0.0}
av['values'] = deque([0.0] * period) # old value queue
def sma(x):
av['values'].append(x)
av['summ'] += x - av['values'].popleft()
av['n'] = min(av['n']+1, period)
return av['summ'] /av['n']
return sma
def create_db():
""" creates database DB_FILE with table sunshine with fields: timestamp, filename, brightness
"""
conn = sqlite3.connect(DB_FILE,
detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
conn.row_factory = sqlite3.Row
with conn:
conn.execute(''' CREATE TABLE IF NOT EXISTS sunshine
(ts timestamp, filename text, brightness real) ''')
def append(filename,brightness,dtime):
""" adds entry to db. the entry parameters are: filename, timestamp, brightness
"""
conn = sqlite3.connect(DB_FILE,
detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
conn.row_factory = sqlite3.Row
with conn:
conn.execute(''' INSERT INTO sunshine (ts,filename,brightness)
VALUES (?,?,?)''',(dtime,filename,brightness))
def query(start,stop,step=None,hour=None):
""" retrieves from the db the filenames, timestamps and brightness from selected start to stop date (datetime objects) with given step between frames. E.g. if frames are taken every hour, then step = 12 means every half-day. If hour is given, then only given hour(s) are taken. In this case step goes over hour-specific entires. E.g. if hour=12 only noon pictures are queried and step=2 means results are given every 2nd day.
"""
conn = sqlite3.connect(DB_FILE,
detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
conn.row_factory = sqlite3.Row
params = ()
main_code = ''' SELECT * FROM sunshine
WHERE (julianday(ts) between julianday(?) AND julianday(?))'''
params_main = (start,stop)
query_code = main_code
params = params_main
if hour:
hour_code = ''' AND abs((julianday(ts)-julianday(?))-round(julianday(ts)-julianday(?)))<0.05/24.0'''
params_hour = ('%d:00'%hour,)*2
query_code += hour_code
params += params_hour
if step:
step_code = ''' AND (rowid - (SELECT rowid FROM sunshine
ORDER BY ts LIMIT 1 )) % ?'''
params_step = (step,)
query_code += step_code
params += params_step
logging.debug(query_code)
logging.debug(params)
with conn:
res = conn.execute(query_code,params)
return res.fetchall()
def query_last_ndays(ndays=30,hour=None,step=None):
""" simplified query where you can ask for the last x days at specific hour
"""
stop = datetime.datetime.now()
start = stop - datetime.timedelta(days=ndays)
return query(start=start,stop=stop,hour=hour,step=step)
# json support
class SunshineJSONEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime.datetime):
return obj.isoformat()
elif isinstance(obj, sqlite3.Row):
d = {}
d.update(obj)
d['ts'] = d['ts'].isoformat()
return d
else:
return super(SunshineJSONEncoder, self).default(obj)
def query_json(start,stop,step=None,hour=None):
raw_data = query(start,stop,step,hour)
return json.dumps(raw_data, cls=SunshineJSONEncoder)
class SunshineJSONEncoder_gcharts(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime.datetime):
return 'Date(%s)'%obj.strftime('%Y,%m,%d,%H,%M,%S')
elif isinstance(obj, sqlite3.Row):
d = {}
d.update(obj)
d['ts'] = 'Date(%s)'%obj.strftime('%Y,%m,%d,%H,%M,%S')
return d
else:
return super(SunshineJSONEncoder, self).default(obj)
def query_google_charts_json(start,stop,step=None,hour=None):
raw_data = query(start,stop,step,hour)
cols = []
cols.append({'id':'ts','label':'date','type':'datetime'})
cols.append({'id':'br','label':'brightness','type':'number'})
cols.append({'id':'br','label':'average','type':'number'})
rows = []
aver = simplemovingaverage(12)
[rows.append({'c':[{'v':x['ts']},{'v':x['brightness']},{'v':aver(x['brightness'])}]}) for x in raw_data]
data = {'cols':cols,'rows':rows}
return json.dumps(data, cls=SunshineJSONEncoder_gcharts)