Add more time range options for viewing tempmon probe readings as graph
This commit is contained in:
parent
92c1b165fb
commit
f086a2aa38
|
@ -8,29 +8,64 @@
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.bundle.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.bundle.min.js"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
||||||
$(function() {
|
var ctx = null;
|
||||||
|
var chart = null;
|
||||||
|
|
||||||
var ctx = $('#tempchart');
|
function fetchReadings(timeRange) {
|
||||||
|
if (timeRange === undefined) {
|
||||||
|
timeRange = $('#time-range').val();
|
||||||
|
}
|
||||||
|
|
||||||
var chart = new Chart(ctx, {
|
var timeUnit;
|
||||||
|
if (timeRange == 'last hour') {
|
||||||
|
timeUnit = 'minute';
|
||||||
|
} else if (['last 6 hours', 'last day'].includes(timeRange)) {
|
||||||
|
timeUnit = 'hour';
|
||||||
|
} else {
|
||||||
|
timeUnit = 'day';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chart) {
|
||||||
|
$('.form-wrapper').mask("Fetching data");
|
||||||
|
chart.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
$.get('${url('{}.graph_readings'.format(route_prefix), uuid=probe.uuid)}', {'time-range': timeRange}, function(data) {
|
||||||
|
|
||||||
|
chart = new Chart(ctx, {
|
||||||
type: 'scatter',
|
type: 'scatter',
|
||||||
data: {
|
data: {
|
||||||
datasets: [{
|
datasets: [{
|
||||||
label: "${probe.description}",
|
label: "${probe.description}",
|
||||||
data: ${json.dumps(readings_data)|n}
|
data: data
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
scales: {
|
scales: {
|
||||||
xAxes: [{
|
xAxes: [{
|
||||||
type: 'time',
|
type: 'time',
|
||||||
time: {unit: 'minute'},
|
time: {unit: timeUnit},
|
||||||
position: 'bottom'
|
position: 'bottom'
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('.form-wrapper').unmask();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
|
||||||
|
ctx = $('#tempchart');
|
||||||
|
|
||||||
|
$('#time-range').selectmenu({
|
||||||
|
change: function(event, ui) {
|
||||||
|
fetchReadings(ui.item.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
fetchReadings();
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -55,9 +90,7 @@
|
||||||
<div class="field-wrapper">
|
<div class="field-wrapper">
|
||||||
<label>Showing</label>
|
<label>Showing</label>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<select name="showing-window" id="showing-window" auto-enhance="true">
|
${time_range}
|
||||||
<option value="last-hour">Last Hour</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -226,9 +226,49 @@ class TempmonProbeView(MasterView):
|
||||||
def graph(self):
|
def graph(self):
|
||||||
probe = self.get_instance()
|
probe = self.get_instance()
|
||||||
|
|
||||||
|
key = 'tempmon.probe.{}.graph_time_range'.format(probe.uuid)
|
||||||
|
selected = self.request.params.get('time-range')
|
||||||
|
if not selected:
|
||||||
|
selected = self.request.session.get(key, 'last hour')
|
||||||
|
self.request.session[key] = selected
|
||||||
|
|
||||||
|
time_range = tags.select('time-range', selected, tags.Options([
|
||||||
|
tags.Option("Last Hour", 'last hour'),
|
||||||
|
tags.Option("Last 6 Hours", 'last 6 hours'),
|
||||||
|
tags.Option("Last Day", 'last day'),
|
||||||
|
tags.Option("Last Week", 'last week'),
|
||||||
|
]))
|
||||||
|
|
||||||
|
context = {
|
||||||
|
'probe': probe,
|
||||||
|
'parent_title': six.text_type(probe),
|
||||||
|
'parent_url': self.get_action_url('view', probe),
|
||||||
|
'time_range': time_range,
|
||||||
|
}
|
||||||
|
return self.render_to_response('graph', context)
|
||||||
|
|
||||||
|
def graph_readings(self):
|
||||||
|
probe = self.get_instance()
|
||||||
|
|
||||||
|
key = 'tempmon.probe.{}.graph_time_range'.format(probe.uuid)
|
||||||
|
selected = self.request.params['time-range']
|
||||||
|
assert selected
|
||||||
|
self.request.session[key] = selected
|
||||||
|
|
||||||
|
# figure out what our window of time is
|
||||||
|
if selected == 'last hour':
|
||||||
|
cutoff = 60 * 60 # seconds x minutes
|
||||||
|
elif selected == 'last 6 hours':
|
||||||
|
cutoff = 60 * 60 * 6 # hour x 6
|
||||||
|
elif selected == 'last day':
|
||||||
|
cutoff = 60 * 60 * 24 # hour x 24
|
||||||
|
elif selected == 'last week':
|
||||||
|
cutoff = 60 * 60 * 24 * 7 # day x 7
|
||||||
|
else:
|
||||||
|
raise NotImplementedError("Unknown time range: {}".format(selected))
|
||||||
|
|
||||||
# figure out which readings we need to graph
|
# figure out which readings we need to graph
|
||||||
# TODO: make this dynamic somehow
|
cutoff = make_utc() - datetime.timedelta(seconds=cutoff)
|
||||||
cutoff = make_utc() - datetime.timedelta(seconds=3600) # last hour
|
|
||||||
readings = self.Session.query(tempmon.Reading)\
|
readings = self.Session.query(tempmon.Reading)\
|
||||||
.filter(tempmon.Reading.probe == probe)\
|
.filter(tempmon.Reading.probe == probe)\
|
||||||
.filter(tempmon.Reading.taken >= cutoff)\
|
.filter(tempmon.Reading.taken >= cutoff)\
|
||||||
|
@ -240,14 +280,7 @@ class TempmonProbeView(MasterView):
|
||||||
'x': localtime(self.rattail_config, reading.taken, from_utc=True).isoformat(),
|
'x': localtime(self.rattail_config, reading.taken, from_utc=True).isoformat(),
|
||||||
'y': float(reading.degrees_f),
|
'y': float(reading.degrees_f),
|
||||||
} for reading in readings]
|
} for reading in readings]
|
||||||
|
return data
|
||||||
context = {
|
|
||||||
'probe': probe,
|
|
||||||
'parent_title': six.text_type(probe),
|
|
||||||
'parent_url': self.get_action_url('view', probe),
|
|
||||||
'readings_data': data,
|
|
||||||
}
|
|
||||||
return self.render_to_response('graph', context)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def defaults(cls, config):
|
def defaults(cls, config):
|
||||||
|
@ -257,10 +290,18 @@ class TempmonProbeView(MasterView):
|
||||||
permission_prefix = cls.get_permission_prefix()
|
permission_prefix = cls.get_permission_prefix()
|
||||||
model_title_plural = cls.get_model_title_plural()
|
model_title_plural = cls.get_model_title_plural()
|
||||||
|
|
||||||
config.add_route('{}.graph'.format(route_prefix), '{}/{{{}}}/graph'.format(url_prefix, model_key))
|
# graph
|
||||||
|
config.add_route('{}.graph'.format(route_prefix), '{}/{{{}}}/graph'.format(url_prefix, model_key),
|
||||||
|
request_method='GET')
|
||||||
config.add_view(cls, attr='graph', route_name='{}.graph'.format(route_prefix),
|
config.add_view(cls, attr='graph', route_name='{}.graph'.format(route_prefix),
|
||||||
permission='{}.view'.format(permission_prefix))
|
permission='{}.view'.format(permission_prefix))
|
||||||
|
|
||||||
|
# graph_readings
|
||||||
|
config.add_route('{}.graph_readings'.format(route_prefix), '{}/{{{}}}/graph-readings'.format(url_prefix, model_key),
|
||||||
|
request_method='GET')
|
||||||
|
config.add_view(cls, attr='graph_readings', route_name='{}.graph_readings'.format(route_prefix),
|
||||||
|
permission='{}.view'.format(permission_prefix), renderer='json')
|
||||||
|
|
||||||
cls._defaults(config)
|
cls._defaults(config)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue