diff options
-rw-r--r-- | ebus/webhdf/__init__.py | 56 | ||||
-rw-r--r-- | ebus/webhdf/static/src/ebus.js | 48 |
2 files changed, 60 insertions, 44 deletions
diff --git a/ebus/webhdf/__init__.py b/ebus/webhdf/__init__.py index 78a85ff..af13f87 100644 --- a/ebus/webhdf/__init__.py +++ b/ebus/webhdf/__init__.py @@ -4,6 +4,8 @@ import json import datetime import time import itertools +import logging +logging.basicConfig(level=logging.DEBUG) import numpy @@ -15,17 +17,6 @@ datastore = ebus.datastore.Datastore("testhdffiles") app = bottle.Bottle("ebus") -def maketime(dt): - """Rechnet CET DateTime in CET timestamp""" - return time.mktime(dt.timetuple())*1000 # - time.altzone)*1000 - -def parsetime(timestamp): - """Macht aus CET timestamp Local DateTime""" - return datetime.datetime.fromtimestamp((timestamp/1000)) # + time.altzone) - -def now(conn): - return conn.execute(text("SELECT CURRENT_TIMESTAMP t")).first().t - @app.route('/') def index_file(): return static_files("index.html") @@ -34,6 +25,7 @@ def index_file(): def static_files(filename): return bottle.static_file(filename, root=os.path.join(os.path.dirname(__file__),"static")) + @app.get('/sensor/:name') def sensor_data_get(name): try: @@ -45,11 +37,12 @@ def sensor_data_get(name): return {'sensor':name,'data':None, 'error':str(e)} @app.put('/sensor/:name') -def sensor_data_put(name): +@app.put('/sensor/:name/:timestamp') +def sensor_data_put(name,timestamp=None): + if not timestamp: timestamp = int(time.time()) try: value = bottle.request.POST.value type = bottle.request.POST.type - timestamp = int(time.time()) if type == "int": klass = ebus.datastore.ValueInt @@ -61,29 +54,53 @@ def sensor_data_put(name): return {'error':'INVALID_TYPE', msg:'Type {0} is invalid'.format(type)} datastore.addValue(name, timestamp, value, klass, flush=True) - - return {'error':None,'msg':"Stored {0} of type {1} with timestamp {2} to {3}".format(value,type,timestamp,name)} + msg = "Stored {0} of type {1} with timestamp {2} to {3}".format(value,type,timestamp,name) + logging.info(msg) + return {'error':None,'msg':msg} except Exception,e: return {'error':e,'msg':e} + @app.route('/sensor/:name/:startdate/:enddate') def sensor_name_start_end(name,startdate,enddate): try: startdate, enddate = int(startdate), int(enddate) + logging.info("/sensor/ start={0} end={1}".format(startdate, enddate)) table=datastore.getTable(name) with datastore: - data = [(x['timestamp']*1000, x['value']) - for x in table.where("(timestamp >= startdate) & (timestamp <= enddate)")] + i = table.where("(timestamp >= startdate) & (timestamp <= enddate)",step=100) + timestamps = [] + try: + for x in range(20): + i.next() + timestamps.append(i['timestamp']) + except: + pass + if len(timestamps) > 10: + diff = map(lambda (x1,x2): (x2-x1)/100, zip(timestamps[:-1], timestamps[1:])) + diff_avg = numpy.average(diff) + time_period = enddate - startdate + samples = time_period / diff_avg + step = numpy.ceil(samples / 400.0) + + data = [(x['timestamp']*1000, x['value']) + for x in table.where("(timestamp >= startdate) & (timestamp <= enddate)", step=step)] + logging.info("diff={0} samples={1} step={2} len={3} ({4})".format(diff_avg, samples, step, len(data),name)) + else: + logging.info("No data found ({0})".format(name)) + data = [] return {'sensor':name, 'error':None,'data':data} except Exception,e: + logging.error("Error: " + str(e) + str(type(e))) return {'sensor':name,'data':None, 'error':str(e)} @app.route('/avg/:name/:startdate') -def sensor_avg_start(name, startdate): - period = 60*15 # 15min +@app.route('/avg/:name/:startdate/:period') +def sensor_avg_start(name, startdate, period=60*15): #15min try: startdate, enddate = int(startdate), int(time.time()) + logging.info("/avg/ start={0} end={1}".format(startdate, enddate)) table=datastore.getTable(name) with datastore: sel_rows = table.where("(timestamp >= startdate) & (timestamp <=enddate)") @@ -95,4 +112,3 @@ def sensor_avg_start(name, startdate): except Exception,e: return {'sensor':name, 'error':str(e), 'data':None} -# vim: autoindent tabstop=4 shiftwidth=4 expandtab softtabstop=4 filetype=python diff --git a/ebus/webhdf/static/src/ebus.js b/ebus/webhdf/static/src/ebus.js index 7667b71..ce37557 100644 --- a/ebus/webhdf/static/src/ebus.js +++ b/ebus/webhdf/static/src/ebus.js @@ -1,15 +1,19 @@ var d = new Object(); -d.sec = 1; +d.ms = 1; +d.sec = 1000 * d.ms; d.min = 60 * d.sec; d.hour = 60 * d.min; d.day = 24 * d.hour; d.week = 7 * d.day; d.month = 30.5 * d.day; - +d.now = new Date().getTime(); + +function int(n) { return Math.round(n); }; + $(document).ready(function(){ - var from = Math.round(new Date().getTime()/1000) - 2*d.day; - var fromOverview = Math.round(new Date().getTime()/1000) - 15*d.day; - var to = Math.round(new Date().getTime()/1000); + var from = d.now - 5*d.day; + var fromOverview = d.now - 30*d.day; + var to = d.now; var datasetDetail = [] var datasetOverview = []; var plotOverview = null; @@ -33,19 +37,13 @@ $(document).ready(function(){ return sensorConfigFound; } var replot = function() { - if (plotDetail == null) { plotDetail = $.plot($("#ebusgraph"), datasetDetail, { - xaxis: { mode: "time"}, + xaxis: { mode: "time", min: from, max:to }, yaxis: { min: -16, max: 100 }, legend: { show : true} }); - } else { - plotDetail.setData(datasetDetail); - plotDetail.draw(); - plotDetail.setupGrid(); // redraw legend - } }; var replotOverview = function() { if (plotOverview == null) { @@ -56,7 +54,7 @@ $(document).ready(function(){ lines: { show: true, lineWidth: 1 }, shadowSize: 0 }, - xaxis: { mode: "time" }, + xaxis: { mode: "time", min: fromOverview, max: d.now }, yaxis: { ticks: [], min: -26, max: 100, autoscaleMargin: 0.1 }, legend: { show: false }, selection: { mode: "x" } @@ -65,7 +63,7 @@ $(document).ready(function(){ plotOverview.setData(datasetOverview); plotOverview.draw(); } - plotOverview.setSelection({xaxis: {'from': from*1000, 'to': to*1000}}, true); + plotOverview.setSelection({xaxis: {'from': from, 'to': to}}, true); }; var plotSensor = function(sensorConfig) { plotSensorDetail(sensorConfig); @@ -76,20 +74,20 @@ $(document).ready(function(){ unplotSensorOverview(sensorname); }; var tzFix = function(d) { - return d - new Date().getTimezoneOffset() * 60 * 1000; + return d; //return d - new Date().getTimezoneOffset() * 60 * 1000; } var plotSensorDetail = function(sensorConfig) { - $.getJSON("sensor/"+escape(sensorConfig.sensorname)+"/"+from+"/"+to, + $.getJSON("sensor/"+escape(sensorConfig.sensorname)+"/"+int(from/1000)+"/"+int(to/1000), function(response) { - if (response['data']) { + if (!response.error) { response.data = response.data.map(function(d) { return [ tzFix(d[0]), d[1] ]; }); datasetDetail.push({'data':response['data'], 'label':sensorConfig.sensorname, 'color':sensorConfig.color}); replot(); } else { - alert("Fehler: " + response["error"]); + console.log("Fehler: " + response["error"]); } }); }; @@ -105,9 +103,9 @@ $(document).ready(function(){ }; var plotSensorOverview = function(sensorConfig) { - $.getJSON("avg/"+escape(sensorConfig.sensorname)+"/"+fromOverview, + $.getJSON("avg/"+escape(sensorConfig.sensorname)+"/"+int(fromOverview/1000), function(response) { - if (response['data']) { + if (!response.error) { response.data = response.data.map(function(d) { return [ tzFix(d[0]), d[1] ]; }); datasetOverview.push({'data':response['data'], 'label':sensorConfig.sensorname, @@ -130,11 +128,12 @@ $(document).ready(function(){ } $("#overview").bind("plotselected", function (event, ranges) { - range_from = Math.round(ranges.xaxis.from / 1000); - range_to = Math.round(ranges.xaxis.to / 1000); + range_from = Math.round(ranges.xaxis.from); + range_to = Math.round(ranges.xaxis.to); // max selection range - if (range_to - range_from > d.month/2) { - plotOverview.setSelection({xaxis: {'from': from*1000, 'to': to*1000}}, true); + if (range_to - range_from > d.month) { + // reset selection + plotOverview.setSelection({xaxis: {'from': from, 'to': to}}, true); return; } else { from = range_from; @@ -177,3 +176,4 @@ $(document).ready(function(){ } }); }); + |