diff --git a/tailbone/templates/tempmon/probes/graph.mako b/tailbone/templates/tempmon/probes/graph.mako new file mode 100644 index 00000000..128fe5ce --- /dev/null +++ b/tailbone/templates/tempmon/probes/graph.mako @@ -0,0 +1,66 @@ +## -*- coding: utf-8; -*- +<%inherit file="/base.mako" /> + +<%def name="title()">Temperature Graph + +<%def name="extra_javascript()"> + ${parent.extra_javascript()} + + + + +
+ +
+ +
+ % if probe.appliance: + ${probe.appliance} + % endif +
+
+ +
+ +
${probe.location}
+
+ +
+ +
+ +
+
+ +
+ + diff --git a/tailbone/templates/tempmon/probes/view.mako b/tailbone/templates/tempmon/probes/view.mako index 8acdbfbe..8bf3fd2e 100644 --- a/tailbone/templates/tempmon/probes/view.mako +++ b/tailbone/templates/tempmon/probes/view.mako @@ -41,6 +41,11 @@ ## rendering methods ############################## +<%def name="context_menu_items()"> + ${parent.context_menu_items()} +
  • ${h.link_to("View Readings as Graph", action_url('graph', instance))}
  • + + <%def name="render_main_fields(form)"> ${form.render_field_readonly('client')} ${form.render_field_readonly('config_key')} diff --git a/tailbone/views/tempmon/probes.py b/tailbone/views/tempmon/probes.py index 7256a0a3..dbb47d78 100644 --- a/tailbone/views/tempmon/probes.py +++ b/tailbone/views/tempmon/probes.py @@ -26,8 +26,11 @@ Views for tempmon probes from __future__ import unicode_literals, absolute_import +import datetime + import six +from rattail.time import make_utc, localtime from rattail_tempmon.db import model as tempmon import colander @@ -220,6 +223,46 @@ class TempmonProbeView(MasterView): g.set_sort_defaults('taken', 'desc') + def graph(self): + probe = self.get_instance() + + # figure out which readings we need to graph + # TODO: make this dynamic somehow + cutoff = make_utc() - datetime.timedelta(seconds=3600) # last hour + readings = self.Session.query(tempmon.Reading)\ + .filter(tempmon.Reading.probe == probe)\ + .filter(tempmon.Reading.taken >= cutoff)\ + .order_by(tempmon.Reading.taken)\ + .all() + + # convert readings to data for scatter plot + data = [{ + 'x': localtime(self.rattail_config, reading.taken, from_utc=True).isoformat(), + 'y': float(reading.degrees_f), + } for reading in readings] + + 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 + def defaults(cls, config): + route_prefix = cls.get_route_prefix() + url_prefix = cls.get_url_prefix() + model_key = cls.get_model_key() + permission_prefix = cls.get_permission_prefix() + model_title_plural = cls.get_model_title_plural() + + config.add_route('{}.graph'.format(route_prefix), '{}/{{{}}}/graph'.format(url_prefix, model_key)) + config.add_view(cls, attr='graph', route_name='{}.graph'.format(route_prefix), + permission='{}.view'.format(permission_prefix)) + + cls._defaults(config) + def includeme(config): TempmonProbeView.defaults(config)