summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYves Fischer <yvesf-git@xapek.org>2011-12-07 23:27:27 +0100
committerYves Fischer <yvesf-git@xapek.org>2011-12-07 23:27:27 +0100
commit2c9b6c09c99eba4939ea1617036ba5bae6889b2a (patch)
tree4e3b7f3a03ad285eb5cd48259510d55fc1cf0198
parent0645c27fbd1082fe70e08a049e2cbb0200fd3cb6 (diff)
downloadebus-alt-2c9b6c09c99eba4939ea1617036ba5bae6889b2a.tar.gz
ebus-alt-2c9b6c09c99eba4939ea1617036ba5bae6889b2a.zip
fix timezone handling
-rw-r--r--ebus/webapp/__init__.py47
-rw-r--r--ebus/webapp/static/console.html68
-rw-r--r--ebus/webapp/static/src/ebus.js6
3 files changed, 69 insertions, 52 deletions
diff --git a/ebus/webapp/__init__.py b/ebus/webapp/__init__.py
index d0e0ff6..9c98ac3 100644
--- a/ebus/webapp/__init__.py
+++ b/ebus/webapp/__init__.py
@@ -9,13 +9,16 @@ from sqlalchemy import text
app = bottle.Bottle("ebus")
-def maketime(datetime):
- """rechnet zeit so um wie Javascript es braucht XXX"""
- return (time.mktime(datetime.timetuple())+time.altzone*-1)*1000
+def maketime(dt):
+ """Rechnet CET DateTime in CET timestamp"""
+ return time.mktime(dt.timetuple())*1000 # - time.altzone)*1000
def parsetime(timestamp):
- """macht aus javascript zeit systemzeit"""
- return ((timestamp/1000) - time.altzone*-1)
+ """Machtaus 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():
@@ -108,11 +111,12 @@ import psycopg2
@app.route('/stream')
@app.route('/stream/:startdate')
def stream(soup, startdate=None):
- time_start = startdate != None and datetime.datetime.fromtimestamp(parsetime(float(startdate))) \
- or datetime.datetime.now()
-
connection = soup.connection()
conn = connection.connection
+
+ time_start = startdate != None and parsetime(float(startdate)) \
+ or now(connection)
+
conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
@@ -120,14 +124,20 @@ def stream(soup, startdate=None):
cursor.execute("LISTEN evt_ebus_value_insert;")
values = []
- if select.select([conn],[],[],10) == ([],[],[]):
- time_stop = datetime.datetime.now()
- else:
- time_stop = datetime.datetime.now()
- conn.poll()
-
- notify = conn.notifies.pop()
- if notify:
+ fails = 0
+ while fails < 5:
+ if select.select([conn],[],[],10) == ([],[],[]):
+ time_stop = now(connection)
+ fails += 1
+ else:
+ conn.poll()
+
+ notify = conn.notifies.pop()
+ if not notify:
+ continue
+
+ time_stop = now(connection)
+ print "time_stop %s"%time_stop
sql = text("""SELECT sensor.name,
value.timestamp,
COALESCE(value.value_int,value.value_float) "value_real",
@@ -144,6 +154,8 @@ def stream(soup, startdate=None):
},
connection.execute(sql, time_start=time_start, time_stop=time_stop))
+ break
+
cursor.close()
return {'time_start' : maketime(time_start), 'time_stop':maketime(time_stop),
'data':values}
@@ -166,6 +178,7 @@ def all_values(soup):
AND value.sensor_id = last_value.sensor_id
AND value.sensor_id = sensor.id""")
+ time_stop = now(conn)
values = map(lambda row: {
"name":row.name,
"timestamp":maketime(row.timestamp),
@@ -173,6 +186,6 @@ def all_values(soup):
"value_string":row.value_string},
conn.execute(sql))
- return {'data':values}
+ return {'data':values, 'time_stop':maketime(time_stop)}
# vim: autoindent tabstop=4 shiftwidth=4 expandtab softtabstop=4 filetype=python
diff --git a/ebus/webapp/static/console.html b/ebus/webapp/static/console.html
index b8b732b..71a861c 100644
--- a/ebus/webapp/static/console.html
+++ b/ebus/webapp/static/console.html
@@ -36,18 +36,10 @@
"tempkollektorWert" : "heizkreisregler9.solarDaten.tempKollektor",
"boilerWert" : "feuerungsautomat1.betriebsdatenRegler1.boilerTemperatur"
};
- function timeToString(timestamp) {
- var d = new Date();
- return dateToString(d);
- }
- function dateToString(d) {
- var f = d3.format("02d");
- return f(d.getHours()) + ":" + f(d.getMinutes()) + ":" + f(d.getSeconds());
- }
- function log(data) {
+ function process(data) {
for (var i in data) {
var row = data[i];
- var caption = "[" + timeToString(row.timestamp) + "] " + row.name + " Value: " + row.value_real + " - " + row.value_string;
+ var caption = "[" + d3.format("02d")(row.timestamp) + "] " + row.name + " Value: " + row.value_real + " - " + row.value_string;
d3.select("#log").insert("div", "div").text(caption);
@@ -62,19 +54,20 @@
function reload(time_stop) {
d3.json("../stream/" + time_stop, function(resp) {
- log(resp.data);
+ process(resp.data);
reload(resp.time_stop);
});
}
d3.xml("draw.svg", "image/svg+xml", function(xml) {
- // Put SVG Data into the DOM
+ // Write SVG Data into the DOM
d3.select("#image")[0][0].appendChild(xml.documentElement);
+
// Create Popup
for (var mapping_element_id in mapping) {
d3.select("#" + mapping_element_id).on("click", function() {
var elem = d3.select( this );
- var sensor_name = mapping[elem.attr("id")];
+ var sensor_name = mapping[elem.attr("id")];
var popup = d3.select("body")
.append("div")
.classed("popup", true)
@@ -86,7 +79,7 @@
popup.append("div")
.text(sensor_name);
- var w = 550, h = 200, margin = 20;
+ var w = 550, h = 200, margin = 30;
var plot = popup.append("svg:svg")
.classed("plot", true)
.attr("width", w)
@@ -108,14 +101,15 @@
y_min = d3.min(data, function(d){return d[1]}),
y_max = d3.max(data, function(d){return d[1]});
- var y = d3.scale.linear()
- .domain([y_min, y_max])
- .range([0+margin, h-margin]);
-
var x = d3.time.scale()
.domain([x_min, x_max])
.range([0+margin, w-margin]);
-
+
+ var y = d3.scale.linear()
+ .domain([y_min, y_max])
+ .range([0+margin, h]);
+
+
var g = plot.append("svg:g")
.attr("transform", "translate(0, "+h+")");
@@ -126,21 +120,15 @@
g.append("svg:path")
.attr("d", line(data));
- // Axes
+ // Axes X-Line
g.append("svg:line")
- .attr("x1", x(x_min))
- .attr("y1", -1 * y(y_min))
+ .attr("x1", 0)
+ .attr("y1", -1*y(y_min))
.attr("x2", x(x_max))
.attr("y2", -1 * y(y_min));
-
- g.append("svg:line")
- .attr("x1", x(x_min))
- .attr("y1", -1*y(y_min))
- .attr("x2", x(x_min))
- .attr("y2", -1*y(y_max));
- // Ticks
+ // Tick Labels
var tick_format = d3.time.format("%d.%m");
g.selectAll(".xlabel")
.data(x.ticks(5)).enter()
@@ -158,18 +146,28 @@
.attr("y", function(d) {return -1*y(d)})
.attr("text-anchor", "right");
+ // X-Lines
+ g.selectAll(".xlines")
+ .data(x.ticks(5)).enter()
+ .append("svg:line")
+ .style("fill", "none")
+ .style("stroke", "#000000")
+ .style("stroke-width", 0.5)
+ .style("stroke-dasharray", "6,1")
+ .attr("x1", function(d){return x(d)})
+ .attr("y1", -1*y(y_min)+(margin/2))
+ .attr("x2", function(d){return x(d)})
+ .attr("y2", -1*y(y_max));
+
+ //
wait_indicator.remove();
});
});
}
d3.json("../all_values", function(resp) {
- log(resp.data);
-
- d3.json("../stream", function(resp) {
- log(resp.data);
- reload(resp.time_stop);
- });
+ process(resp.data);
+ reload(resp.time_stop);
});
});
</script>
diff --git a/ebus/webapp/static/src/ebus.js b/ebus/webapp/static/src/ebus.js
index ba14f51..46a9ed8 100644
--- a/ebus/webapp/static/src/ebus.js
+++ b/ebus/webapp/static/src/ebus.js
@@ -66,10 +66,15 @@ $(document).ready(function(){
unplotSensorDetail(sensorname);
unplotSensorOverview(sensorname);
};
+ var tzFix = function(d) {
+ return d - new Date().getTimezoneOffset() * 60 * 1000;
+ }
+
var plotSensorDetail = function(sensorConfig) {
$.getJSON("sensor/"+escape(sensorConfig.sensorname)+"/"+from+"/"+to,
function(response) {
if (response['data']) {
+ response.data = response.data.map(function(d) { return [ tzFix(d[0]), d[1] ]; });
datasetDetail.push({'data':response['data'],
'label':sensorConfig.sensorname,
'color':sensorConfig.color});
@@ -94,6 +99,7 @@ $(document).ready(function(){
$.getJSON("sensor_cached/"+escape(sensorConfig.sensorname)+"/"+fromOverview, //+"/"+to,
function(response) {
if (response['data']) {
+ response.data = response.data.map(function(d) { return [ tzFix(d[0]), d[1] ]; });
datasetOverview.push({'data':response['data'],
'label':sensorConfig.sensorname,
'color':sensorConfig.color});