Project

General

Profile

Statistics
| Branch: | Revision:

gdp-if / visualization / server.py @ master

History | View | Annotate | Download (4.28 KB)

1
#!/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
from twisted.web.resource import Resource, NoResource
9
from twisted.web.server import Site
10
from twisted.web import static
11
from threading import Lock
12

    
13
from gdp import GDPcache
14
import argparse
15
import json
16
import gviz_api
17
from datetime import datetime
18
import time
19

    
20
class DataResource(Resource):
21

    
22
    isLeaf = True
23
    def __init__(self):
24
        Resource.__init__(self)
25
        self.GDPcaches = {}
26
        self.lock = Lock()
27

    
28

    
29
    def __handleQuery(self, request):
30

    
31
        args = request.args
32

    
33
        # get query parameters
34
        logname = args['logname'][0]
35
        startTime = float(args['startTime'][0])
36
        endTime = float(args['endTime'][0])
37

    
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
        self.lock.acquire()
48
        gdpcache = self.GDPcaches.get(logname, None)
49
        if gdpcache is None:
50
            gdpcache = GDPcache(logname)
51
            self.GDPcaches[logname] = gdpcache
52
        self.lock.release()
53

    
54
        sampleRecord = gdpcache.mostRecent()
55
        sampleData = json.loads(sampleRecord['data'])
56
        if sampleData.get('device') == "BLEES":
57
            keys = ['pressure_pascals', 'humidity_percent',
58
                    'temperature_celcius', 'light_lux',
59
                    'acceleration_advertisement', 'acceleration_interval']
60
        elif sampleData.get('device') == "Blink":
61
            keys = ['current_motion', 'motion_since_last_adv',
62
                    'motion_last_minute']
63
        elif sampleData.get('device') == 'PowerBlade':
64
            keys = ['rms_voltage', 'power', 'apparent_power', 'energy',
65
                    'power_factor']
66
        elif (('msp432_active' in sampleData.keys()) and
67
                ('cc2650_active' in sampleData.keys())):
68
            keys = ['rhum', 'tamb', 'press', 'bat', 'lux']
69
        else:
70
            keys = []
71

    
72
        # create data
73
        data = []
74
        for datum in gdpcache.getRange(startTime, endTime):
75

    
76
            _time = datetime.fromtimestamp(datum['ts']['tv_sec'] + \
77
                                (datum['ts']['tv_nsec']*1.0/10**9))
78
            __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
        data_table = gviz_api.DataTable(desc)
94
        data_table.LoadData(data)
95

    
96
        response = data_table.ToJSonResponse(order_by='time', req_id = reqId)
97

    
98
        return response
99

    
100

    
101
    def render_GET(self, request):
102

    
103
        resp = ""
104
        respCode = 200
105

    
106
        try:
107
            resp = self.__handleQuery(request)
108
        except Exception as e:
109
            print e
110
            request.setResponseCode(500)
111
            respCode = 500
112
            resp = str(e)
113

    
114
        return resp
115

    
116

    
117
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

    
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
    parser.add_argument("-l", "--logfile", default="visServer.log",
142
                        help="Logfile to log requests to")
143

    
144
    args = parser.parse_args()
145
    site = Site(MainResource(), logPath=args.logfile)
146
    reactor.listenTCP(args.port, site)
147

    
148
    print "Starting web-server on port", args.port
149
    reactor.run()
150