update plot interface with point number selection and pause
This commit is contained in:
parent
c180ce9ea6
commit
a81d2cc6a1
5
app.py
5
app.py
|
@ -87,7 +87,10 @@ def recipe():
|
||||||
@socketio.on('new client')
|
@socketio.on('new client')
|
||||||
def handle_new_client():
|
def handle_new_client():
|
||||||
updateState()
|
updateState()
|
||||||
socketio.emit('sensor history', sensors.get_history())
|
|
||||||
|
@socketio.on('get sensors history')
|
||||||
|
def send_sensors_history(elements=1000):
|
||||||
|
socketio.emit('sensor history', sensors.get_history(elements))
|
||||||
|
|
||||||
@socketio.on('manual response')
|
@socketio.on('manual response')
|
||||||
def handle_manual_response(response):
|
def handle_manual_response(response):
|
||||||
|
|
|
@ -63,6 +63,26 @@ function applyState(newstate) {
|
||||||
var enable_draw = true;
|
var enable_draw = true;
|
||||||
var plot_data = {};
|
var plot_data = {};
|
||||||
|
|
||||||
|
function toggle_update_plot() {
|
||||||
|
enable_draw = !enable_draw;
|
||||||
|
}
|
||||||
|
function pause_plotting() {enable_draw = false;}
|
||||||
|
function resume_plotting() {enable_draw = true;}
|
||||||
|
function set_plot_points(value) {
|
||||||
|
let current = localstate.maxpoints;
|
||||||
|
if (value === undefined) {
|
||||||
|
value = parseInt(document.getElementById('point-number').value);
|
||||||
|
}
|
||||||
|
localstate.maxpoints = value;
|
||||||
|
if (value <= current) {
|
||||||
|
// we alredy have all the points we want just set it and let other
|
||||||
|
// function discard extra points
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Ask for more data
|
||||||
|
socket.emit('get sensors history', value);
|
||||||
|
}
|
||||||
|
|
||||||
function add_plot_data(newpoints, render=true) {
|
function add_plot_data(newpoints, render=true) {
|
||||||
for (var i = 0; i < newpoints.length; ++i) {
|
for (var i = 0; i < newpoints.length; ++i) {
|
||||||
let point = newpoints[i]
|
let point = newpoints[i]
|
||||||
|
@ -77,6 +97,8 @@ function add_plot_data(newpoints, render=true) {
|
||||||
}
|
}
|
||||||
plot_data[key].x.push(point[1]);
|
plot_data[key].x.push(point[1]);
|
||||||
plot_data[key].y.push(point[2]);
|
plot_data[key].y.push(point[2]);
|
||||||
|
// This is different since we want maxpoints to be the absolute max, not
|
||||||
|
// for each variable, but good enough for now (or the opposite?)
|
||||||
while (plot_data[key].x.length > localstate.maxpoints) {
|
while (plot_data[key].x.length > localstate.maxpoints) {
|
||||||
plot_data[key].x.shift();
|
plot_data[key].x.shift();
|
||||||
plot_data[key].y.shift();
|
plot_data[key].y.shift();
|
||||||
|
@ -85,28 +107,19 @@ function add_plot_data(newpoints, render=true) {
|
||||||
if (render) render_plot();
|
if (render) render_plot();
|
||||||
}
|
}
|
||||||
|
|
||||||
// function set_plot_points(maxpoints) {
|
|
||||||
// let more = localstate.maxpoints > maxpoints;
|
|
||||||
// localstate.maxpoints = maxpoints;
|
|
||||||
// if (more) {
|
|
||||||
// for (key in plot_data.keys())
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
function render_plot() {
|
function render_plot() {
|
||||||
if (enable_draw && document.getElementById("data-plot") !== null) {
|
if (enable_draw && document.getElementById("data-plot") !== null) {
|
||||||
Plotly.newPlot('data-plot', Object.values(plot_data));
|
Plotly.newPlot('data-plot', Object.values(plot_data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function render_actuators(data) {
|
function render_actuators(data) {
|
||||||
let html = document.getElementById("actuator-list");
|
let html = document.getElementById("actuator-list");
|
||||||
if (data === undefined || html === null) return;
|
if (data === undefined || html === null) return;
|
||||||
let template = `<div class="content">
|
let template = `<div class="content">
|
||||||
Total Consumption: {{total}}W<br>
|
Total Consumption: {{total}}Wh<br>
|
||||||
{{#consumption}}
|
{{#consumption}}
|
||||||
{{name}}: {{W}}W</br>
|
{{name}}: {{Wh}}Wh</br>
|
||||||
{{/consumption}}
|
{{/consumption}}
|
||||||
</div>`;
|
</div>`;
|
||||||
let total = 0;
|
let total = 0;
|
||||||
|
@ -114,7 +127,7 @@ function render_actuators(data) {
|
||||||
for (var key in data.consumption){
|
for (var key in data.consumption){
|
||||||
let val = data.consumption[key];
|
let val = data.consumption[key];
|
||||||
total += val;
|
total += val;
|
||||||
out.push({name: key, W: val.toFixed(2)});
|
out.push({name: key, Wh: val.toFixed(2)});
|
||||||
}
|
}
|
||||||
|
|
||||||
html.innerHTML = Mustache.render(template, { total: total.toFixed(2),
|
html.innerHTML = Mustache.render(template, { total: total.toFixed(2),
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from time import perf_counter
|
from time import perf_counter
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from collections import deque
|
from collections import deque
|
||||||
|
from itertools import islice
|
||||||
import re
|
import re
|
||||||
from os.path import exists
|
from os.path import exists
|
||||||
|
|
||||||
|
@ -178,8 +179,9 @@ class Sensors():
|
||||||
def get(self):
|
def get(self):
|
||||||
return self.value_tuple()
|
return self.value_tuple()
|
||||||
|
|
||||||
def get_history(self):
|
def get_history(self, n=None):
|
||||||
return tuple(self.history)
|
l = len(self.history)
|
||||||
|
return tuple(islice(self.history, max(0, l - n), l))
|
||||||
|
|
||||||
sensors = Sensors()
|
sensors = Sensors()
|
||||||
|
|
||||||
|
|
|
@ -26,11 +26,16 @@
|
||||||
render_sensors(data);
|
render_sensors(data);
|
||||||
});
|
});
|
||||||
socket.on("sensor history", (...data) => {
|
socket.on("sensor history", (...data) => {
|
||||||
|
// first clear everything
|
||||||
|
plot_data = {};
|
||||||
|
// then add new data
|
||||||
enable_draw = false;
|
enable_draw = false;
|
||||||
data.forEach(add_plot_data);
|
data.forEach(add_plot_data);
|
||||||
enable_draw = true;
|
enable_draw = true;
|
||||||
render_plot();
|
render_plot();
|
||||||
});
|
});
|
||||||
|
// sane default?
|
||||||
|
socket.emit('get sensors history', 200);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
window.onload = setup;
|
window.onload = setup;
|
||||||
|
|
|
@ -36,8 +36,19 @@
|
||||||
</p>
|
</p>
|
||||||
</header>
|
</header>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div id="data-plot"></div>
|
<div class="field has-addons">
|
||||||
|
<button class="button is-link" onclick="toggle_update_plot()">Pause/Unpause Plot</button>
|
||||||
|
<div class="control">
|
||||||
|
<input class="input" type="number"/ value="1000" id="point-number" />
|
||||||
|
</div>
|
||||||
|
<div class="control">
|
||||||
|
<a class="button is-info" onclick="set_plot_points()">
|
||||||
|
Update #of points
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="data-plot"></div>
|
||||||
<br/>
|
<br/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
4
utils.py
4
utils.py
|
@ -9,8 +9,8 @@ def consumption_diff(before, after):
|
||||||
def consumption_to_string(dic):
|
def consumption_to_string(dic):
|
||||||
out = ''
|
out = ''
|
||||||
for key in dic:
|
for key in dic:
|
||||||
out += '{0:s}:\t{1:.2f}W\n'.format(key, dic[key])
|
out += '{0:s}:\t{1:.2f}Wh\n'.format(key, dic[key])
|
||||||
out += 'Total:\t{0:.2f}W'.format(sum(dic.values()))
|
out += 'Total:\t{0:.2f}Wh'.format(sum(dic.values()))
|
||||||
return out
|
return out
|
||||||
|
|
||||||
def stohms(s):
|
def stohms(s):
|
||||||
|
|
Loading…
Reference in New Issue