2 * Graph sensor and/or actuator values
5 //TODO: Clean this file up, I bow to Jeremy's superior JavaScript knowledge
10 mctx.graph.api.sensors = mctx.api + "sensors";
11 mctx.graph.api.actuators = mctx.api + "actuators";
14 mctx.graph.dependent = null;
15 mctx.graph.independent = null;
16 mctx.graph.timer = null;
17 mctx.graph.running = false;
18 mctx.graph.chart = null;
21 * Helper - Calculate pairs of (dependent, independent) values
22 * Given input as (time, value) pairs for dependent and independent
23 * Appends each value pair to the result
26 function dataMerge(dependent, independent, result) {
28 for (var i = 0; i < dependent.length-1; ++i) {
29 var start = dependent[i][0];
30 var end = dependent[i+1][0];
31 var average = 0, n = 0;
32 for (; j < independent.length; ++j) {
33 if (independent[j][0] < start)
35 else if (independent[j][0] >= end)
37 average += independent[j][1];
42 result.push([dependent[i][1], average]);
49 * Helper function adds the sensors and actuators to a form
50 * @param input_type is it a radio? or is it a checkbox?
51 * @param check_first determines whether the first item is checked or not
52 * @param group which group this input belongs to (name field)
54 $.fn.deployDevices = function(input_type, check_first, group) {
56 var apply = function(dict, prefix) {
57 $.each(dict, function(key, val) {
59 'type' : input_type, 'value' : key, 'alt' : val,
60 'class' : prefix, 'name' : group,
61 'id' : prefix + '_' + val //Unique id (name mangling)
63 var entry = $("<input/>", attributes);
64 var label = $("<label/>", {'for' : prefix + '_' + val, 'text' : val});
65 entry.prop("checked", check_first);
67 container.append(entry).append(label);
71 apply(mctx.sensors, 'sensors');
72 apply(mctx.actuators, 'actuators');
76 * Identify sensors/actuators
77 * @returns itself (Is this right?)
79 $.fn.setDevices = function() {
80 // Query for sensors and actuators
82 url : mctx.api + 'identify',
83 data : {'sensors' : 1, 'actuators' : 1}
84 }).done(function (data) {
85 mctx.sensors = $.extend(mctx.sensors, data.sensors);
86 mctx.actuators = $.extend(mctx.actuators, data.actuators);
88 //Always set the 'time' option to be checked
89 $("#xaxis input").prop('checked', true);
90 $("#xaxis").deployDevices("radio", false, 'xaxis');
91 $("#yaxis").deployDevices("checkbox", true, 'yaxis');
92 $("#current_time").val(data.running_time);
93 //Add event listeners for when the
94 $(".change input").change(function () {
95 $("#graph").setGraph();
100 function graphUpdater() {
102 'sensors' : mctx.graph.api.sensors,
103 'actuators' : mctx.graph.api.actuators
106 var updater = function () {
109 var ctime = $("#current_time");
111 var xaxis = mctx.graph.xaxis;
112 var yaxis = mctx.graph.yaxis;
113 var start_time = mctx.graph.start_time;
114 var end_time = mctx.graph.end_time;
115 var devices = mctx.graph.devices;
117 if (xaxis.size() < 1 || yaxis.size() < 1) {
118 mctx.graph.running = false;
122 $.each(devices, function(key, val) {
123 if (val.urltype in urls) {
124 var parameters = {id : val.id};
125 if (start_time != null) {
126 parameters.start_time = start_time;
128 if (end_time != null) {
129 parameters.end_time = end_time;
131 responses.push($.ajax({url : urls[val.urltype], data : parameters})
132 .done(function(json) {
133 //alert("Hi from " + json.name);
135 for (var i = 0; i < json.data.length; ++i) {
136 if (dev.length <= 0 || json.data[i][0] > dev[dev.length-1][0]) {
137 dev.push(json.data[i]);
140 ctime.val(json.running_time);
141 //alert(devices[json.name].data);
146 //... When the response is received, then() will happen (I think?)
147 $.when.apply(this, responses).then(function () {
149 yaxis.each(function() {
150 //alert("Add " + $(this).val() + " to plot");
151 if (xaxis.attr("alt") === "time") {
152 //alert("Against time");
153 plot_data.push(devices[$(this).attr("alt")].data);
156 dataMerge(devices[xaxis.attr("alt")].data, devices[$(this).attr("alt")].data, result);
159 for (var i = 0; i < result.length; ++i)
160 astr += "[" + result[i][0] + "," + result[i][1] + "]" + ",";
164 plot_data.push(result);
168 //$.plot("#graph", plot_data);
169 if (mctx.graph.chart !== null) {
170 mctx.graph.chart.setData(plot_data);
171 mctx.graph.chart.setupGrid();
172 mctx.graph.chart.draw();
174 mctx.graph.chart = $.plot("#graph", plot_data);
176 if (mctx.graph.running) {
177 mctx.graph.timer = setTimeout(updater, 1000);
179 }, function () {mctx.graph.running=false; alert("Graph crashed");});
182 mctx.graph.running = true;
188 * Sets the graphs to graph stuff.
191 $.fn.setGraph = function () {
192 // Determine which actuator/sensors to plot
193 var xaxis = $("#xaxis input[name=xaxis]:checked");
194 var yaxis = $("#yaxis input[name=yaxis]:checked");
195 if (xaxis.size() < 1 || yaxis.size() < 1) {
200 var start_time = $("#start_time").val();
201 var end_time = $("#end_time").val();
202 if (!$.isNumeric(start_time)) {
205 if (!$.isNumeric(end_time)) {
210 var populateDict = function () {
212 dict['urltype'] = $(this).attr("class");
213 dict['id'] = $(this).attr("value");
215 dict['start_time'] = start_time;
216 dict['end_time'] = end_time;
217 devices[$(this).attr("alt")] = dict;
219 xaxis.each(populateDict);
220 yaxis.each(populateDict);
222 mctx.graph.xaxis = xaxis;
223 mctx.graph.yaxis = yaxis;
224 mctx.graph.start_time = start_time;
225 mctx.graph.end_time = end_time;
226 mctx.graph.devices = devices;
228 if (!mctx.graph.running) {
229 $("#graph-run").val("Pause");
236 $.fn.runButton = function() {
237 //alert($(this).val());
238 if ($(this).val() === "Run") {
239 $("#graph").setGraph();
240 $(this).val("Pause");
243 mctx.graph.running = false;
244 clearTimeout(mctx.graph.timer);