Add more time range options for viewing tempmon probe readings as graph

This commit is contained in:
Lance Edgar 2018-10-25 15:57:25 -05:00
parent 92c1b165fb
commit f086a2aa38
2 changed files with 105 additions and 31 deletions

View file

@ -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">
var ctx = null;
var chart = null;
function fetchReadings(timeRange) {
if (timeRange === undefined) {
timeRange = $('#time-range').val();
}
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',
data: {
datasets: [{
label: "${probe.description}",
data: data
}]
},
options: {
scales: {
xAxes: [{
type: 'time',
time: {unit: timeUnit},
position: 'bottom'
}]
}
}
});
$('.form-wrapper').unmask();
});
}
$(function() { $(function() {
var ctx = $('#tempchart'); ctx = $('#tempchart');
var chart = new Chart(ctx, { $('#time-range').selectmenu({
type: 'scatter', change: function(event, ui) {
data: { fetchReadings(ui.item.value);
datasets: [{
label: "${probe.description}",
data: ${json.dumps(readings_data)|n}
}]
},
options: {
scales: {
xAxes: [{
type: 'time',
time: {unit: 'minute'},
position: 'bottom'
}]
}
} }
}); });
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>

View file

@ -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)