gdp-if / visualization / server.py @ master
History | View | Annotate | Download (4.28 KB)
1 | 691f36bc | Nitesh Mor | #!/usr/bin/env python
|
---|---|---|---|
2 | |||
3 | """
|
||
4 | A visualization tool for time-series data stored in GDP logs
|
||
5 | """
|
||
6 | |||
7 | from twisted.internet import reactor |
||
8 | 556292c9 | Nitesh Mor | from twisted.web.resource import Resource, NoResource |
9 | 691f36bc | Nitesh Mor | from twisted.web.server import Site |
10 | 556292c9 | Nitesh Mor | from twisted.web import static |
11 | ef293a24 | Nitesh Mor | from threading import Lock |
12 | 691f36bc | Nitesh Mor | |
13 | 3ba532f9 | Nitesh Mor | from gdp import GDPcache |
14 | 691f36bc | Nitesh Mor | import argparse |
15 | import json |
||
16 | import gviz_api |
||
17 | from datetime import datetime |
||
18 | 2f19a3c6 | Nitesh Mor | import time |
19 | 691f36bc | Nitesh Mor | |
20 | class DataResource(Resource): |
||
21 | |||
22 | isLeaf = True
|
||
23 | def __init__(self): |
||
24 | Resource.__init__(self)
|
||
25 | 5d99f559 | Nitesh Mor | self.GDPcaches = {}
|
26 | ef293a24 | Nitesh Mor | self.lock = Lock()
|
27 | 691f36bc | Nitesh Mor | |
28 | |||
29 | def __handleQuery(self, request): |
||
30 | |||
31 | args = request.args |
||
32 | |||
33 | 2f19a3c6 | Nitesh Mor | # get query parameters
|
34 | logname = args['logname'][0] |
||
35 | 5d99f559 | Nitesh Mor | startTime = float(args['startTime'][0]) |
36 | endTime = float(args['endTime'][0]) |
||
37 | 2f19a3c6 | Nitesh Mor | |
38 | # reqId processing
|
||
39 | reqId = 0
|
||
40 | tqx = args['tqx'][0].split(';') |
||
41 | for t in tqx: |
||
42 | _t = t.split(':')
|
||
43 | if _t[0] == "reqId": |
||
44 | reqId = _t[1]
|
||
45 | break
|
||
46 | |||
47 | ef293a24 | Nitesh Mor | self.lock.acquire()
|
48 | 5d99f559 | Nitesh Mor | gdpcache = self.GDPcaches.get(logname, None) |
49 | if gdpcache is None: |
||
50 | gdpcache = GDPcache(logname) |
||
51 | self.GDPcaches[logname] = gdpcache
|
||
52 | ef293a24 | Nitesh Mor | self.lock.release()
|
53 | 2f19a3c6 | Nitesh Mor | |
54 | 5d99f559 | Nitesh Mor | sampleRecord = gdpcache.mostRecent() |
55 | a395bab1 | Nitesh Mor | sampleData = json.loads(sampleRecord['data'])
|
56 | 2b0ac3be | Nitesh Mor | if sampleData.get('device') == "BLEES": |
57 | a395bab1 | Nitesh Mor | keys = ['pressure_pascals', 'humidity_percent', |
58 | 7eb3d57e | Nitesh Mor | 'temperature_celcius', 'light_lux', |
59 | 'acceleration_advertisement', 'acceleration_interval'] |
||
60 | 2b0ac3be | Nitesh Mor | elif sampleData.get('device') == "Blink": |
61 | a395bab1 | Nitesh Mor | keys = ['current_motion', 'motion_since_last_adv', |
62 | 'motion_last_minute']
|
||
63 | 2b0ac3be | Nitesh Mor | elif sampleData.get('device') == 'PowerBlade': |
64 | a395bab1 | Nitesh Mor | keys = ['rms_voltage', 'power', 'apparent_power', 'energy', |
65 | 'power_factor']
|
||
66 | 2b0ac3be | Nitesh Mor | elif (('msp432_active' in sampleData.keys()) and |
67 | ('cc2650_active' in sampleData.keys())): |
||
68 | keys = ['rhum', 'tamb', 'press', 'bat', 'lux'] |
||
69 | a395bab1 | Nitesh Mor | else:
|
70 | keys = [] |
||
71 | 2f19a3c6 | Nitesh Mor | |
72 | # create data
|
||
73 | data = [] |
||
74 | 72878200 | Nitesh Mor | for datum in gdpcache.getRange(startTime, endTime): |
75 | 2f19a3c6 | Nitesh Mor | |
76 | _time = datetime.fromtimestamp(datum['ts']['tv_sec'] + \ |
||
77 | (datum['ts']['tv_nsec']*1.0/10**9)) |
||
78 | a395bab1 | Nitesh Mor | __xxx = [_time] |
79 | for key in keys: |
||
80 | _raw_data = json.loads(datum['data'])[key]
|
||
81 | if _raw_data == "true": |
||
82 | _data = 1.0
|
||
83 | elif _raw_data == "false": |
||
84 | _data = 0.0
|
||
85 | else:
|
||
86 | _data = float(_raw_data)
|
||
87 | __xxx.append(_data) |
||
88 | data.append(tuple(__xxx))
|
||
89 | |||
90 | desc = [('time', 'datetime')] |
||
91 | for key in keys: |
||
92 | desc.append((key, 'number'))
|
||
93 | 2f19a3c6 | Nitesh Mor | data_table = gviz_api.DataTable(desc) |
94 | data_table.LoadData(data) |
||
95 | |||
96 | a395bab1 | Nitesh Mor | response = data_table.ToJSonResponse(order_by='time', req_id = reqId)
|
97 | 691f36bc | Nitesh Mor | |
98 | 2f19a3c6 | Nitesh Mor | return response
|
99 | 691f36bc | Nitesh Mor | |
100 | |||
101 | def render_GET(self, request): |
||
102 | |||
103 | 2f19a3c6 | Nitesh Mor | resp = ""
|
104 | respCode = 200
|
||
105 | 691f36bc | Nitesh Mor | |
106 | 556292c9 | Nitesh Mor | try:
|
107 | resp = self.__handleQuery(request)
|
||
108 | except Exception as e: |
||
109 | print e
|
||
110 | request.setResponseCode(500)
|
||
111 | respCode = 500
|
||
112 | 3b5d2cf3 | Nitesh Mor | resp = str(e)
|
113 | 556292c9 | Nitesh Mor | |
114 | 2f19a3c6 | Nitesh Mor | return resp
|
115 | 691f36bc | Nitesh Mor | |
116 | |||
117 | 556292c9 | Nitesh Mor | class MainResource(Resource): |
118 | |||
119 | def __init__(self): |
||
120 | Resource.__init__(self)
|
||
121 | self.staticresource = static.File("./static") |
||
122 | self.dataresource = DataResource()
|
||
123 | self.putChild('static', self.staticresource) |
||
124 | self.putChild('datasource', self.dataresource) |
||
125 | |||
126 | def getChild(self, name, request): |
||
127 | if name == "": |
||
128 | return self |
||
129 | else:
|
||
130 | return NoResource()
|
||
131 | |||
132 | def render_GET(self, request): |
||
133 | with open('index.html') as fh: |
||
134 | return fh.read()
|
||
135 | 691f36bc | Nitesh Mor | |
136 | if __name__ == '__main__': |
||
137 | |||
138 | parser = argparse.ArgumentParser() |
||
139 | parser.add_argument("-p", "--port", type=int, default=8888, |
||
140 | help="TCP port to serve requests on")
|
||
141 | 556292c9 | Nitesh Mor | parser.add_argument("-l", "--logfile", default="visServer.log", |
142 | help="Logfile to log requests to")
|
||
143 | 691f36bc | Nitesh Mor | |
144 | args = parser.parse_args() |
||
145 | 556292c9 | Nitesh Mor | site = Site(MainResource(), logPath=args.logfile) |
146 | 691f36bc | Nitesh Mor | reactor.listenTCP(args.port, site) |
147 | |||
148 | print "Starting web-server on port", args.port |
||
149 | reactor.run() |