Project

General

Profile

Statistics
| Branch: | Revision:

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()