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";
15 mctx.graph.devices = {};
16 mctx.graph.dependent = null;
17 mctx.graph.independent = null;
18 mctx.graph.timer = null;
19 mctx.graph.running = false;
20 mctx.graph.chart = null;
23 * Helper - Calculate pairs of (dependent, independent) values
24 * Given input as (time, value) pairs for dependent and independent
25 * Appends each value pair to the result
29 * Helper - Calculate pairs of (dependent, independent) values
30 * Given input as (time, value) pairs for dependent and independent
31 * Appends each value pair to the result
32 * @param {array[][]} dependent Dependent data to be correlated with independent
33 * @param {array[][]} independent Independent data
34 * @param {array[][]} result Storage location
35 * @returns {dataMerge.result}
37 function dataMerge(dependent, independent, result) {
39 for (var i = 0; i < dependent.length-1; ++i) {
40 var start = dependent[i][0];
41 var end = dependent[i+1][0];
42 var average = 0, n = 0;
43 for (; j < independent.length; ++j) {
44 if (independent[j][0] < start)
46 else if (independent[j][0] >= end)
48 average += independent[j][1];
53 result.push([dependent[i][1], average]);
60 * Helper function adds the sensors and actuators to a form
61 * @param input_type is it a radio? or is it a checkbox?
62 * @param check_first determines whether the first item is checked or not
63 * @param group which group this input belongs to (name field)
65 $.fn.deployDevices = function(input_type, check_first, group) {
67 var apply = function(dict, prefix) {
68 $.each(dict, function(key, val) {
69 //Unique id (name mangling)
70 var id = container.attr('id') + "_" + prefix + "_" + val.name;
73 'type' : input_type, 'value' : key, 'alt' : val.name,
74 'class' : prefix, 'name' : group,
78 var entry = $("<input/>", attributes);
79 var label = $("<label/>", {'for' : id, 'text' : val.name});
80 entry.prop("checked", check_first);
82 container.append(entry).append(label);
86 apply(mctx.sensors, 'sensors');
87 apply(mctx.actuators, 'actuators');
91 * Identify sensors/actuators
92 * @returns itself (Is this right?)
94 $.fn.setDevices = function() {
95 // Query for sensors and actuators
97 url : mctx.api + 'identify',
98 data : {'sensors' : 1, 'actuators' : 1}
99 }).done(function (data) {
100 mctx.sensors = $.extend(mctx.sensors, data.sensors);
101 mctx.actuators = $.extend(mctx.actuators, data.actuators);
103 //Always set the 'time' option to be checked
104 $("#xaxis input").prop('checked', true);
105 $("#xaxis").deployDevices("radio", false, 'xaxis');
106 $("#yaxis").deployDevices("checkbox", true, 'yaxis');
107 $("#current_time").val(data.running_time);
108 //Add event listeners for when the
109 $(".change input").change(function () {
110 $("#graph").setGraph();
115 function setGraphStatus(on, failText, keep) {
117 mctx.graph.running = true;
118 $("#status-text").html(" ");
119 $("#graph-run").prop("value", "Pause");
121 mctx.graph.running = false;
123 $("#status-text").text(failText).addClass("fail");
125 $("#status-text").text("Graph stopped").removeClass("fail");
127 $("#graph-run").prop("value", "Run");
131 function graphUpdater() {
133 'sensors' : mctx.graph.api.sensors,
134 'actuators' : mctx.graph.api.actuators
137 var updater = function () {
139 var ctime = $("#current_time");
141 var xaxis = mctx.graph.xaxis;
142 var yaxis = mctx.graph.yaxis;
143 var start_time = mctx.graph.start_time;
144 var end_time = mctx.graph.end_time;
145 var devices = mctx.graph.devices;
147 if (xaxis.size() < 1 || yaxis.size() < 1) {
148 setGraphStatus(false, "No x or y axis selected.");
152 $.each(devices, function(key, val) {
153 if (val.urltype in urls) {
154 var parameters = {id : val.id};
155 if (start_time !== null) {
156 parameters.start_time = start_time;
158 if (end_time !== null) {
159 parameters.end_time = end_time;
161 responses.push($.ajax({url : urls[val.urltype], data : parameters})
162 .done(function(json) {
163 //alert("Hi from " + json.name);
164 if (!$("#status-text").checkStatus(json)) {
165 setGraphStatus(false, null, true); //Don't reset text, checkstatus just set it.
170 for (var i = 0; i < json.data.length; ++i) {
171 if (dev.length <= 0 || json.data[i][0] > dev[dev.length-1][0]) {
172 dev.push(json.data[i]);
175 ctime.val(json.running_time);
176 //alert(devices[json.name].data);
181 //... When the response is received, then() will happen (I think?)
182 $.when.apply(this, responses).then(function () {
183 if (mctx.graph.running) {
186 yaxis.each(function() {
188 series.label = $(this).attr("alt");
190 //alert("Add " + $(this).val() + " to plot");
191 if (xaxis.attr("alt") === "time") {
192 //alert("Against time");
193 series.data = devices[$(this).attr("alt")].data;
196 dataMerge(devices[xaxis.attr("alt")].data,
197 devices[$(this).attr("alt")].data, result);
198 series.data = result;
200 plot_data.push(series);
203 if (mctx.graph.chart !== null) {
204 mctx.graph.chart.setData(plot_data);
205 mctx.graph.chart.setupGrid();
206 mctx.graph.chart.draw();
210 container : "#graph-legend"
213 mctx.graph.chart = $.plot("#graph", plot_data, options);
215 mctx.graph.timer = setTimeout(updater, 1000);
218 setGraphStatus("Connection issue - graph stopped.");
219 //This will always happen when a user closes the page
220 //alert("Graph crashed");
224 setGraphStatus(true);
230 * Sets the graphs to graph stuff.
233 $.fn.setGraph = function () {
234 // Determine which actuator/sensors to plot
235 var xaxis = $("#xaxis input[name=xaxis]:checked");
236 var yaxis = $("#yaxis input[name=yaxis]:checked");
237 if (xaxis.size() < 1 || yaxis.size() < 1) {
239 setGraphStatus(false, "No x or y axis selected.");
243 var start_time = $("#start_time").val();
244 var end_time = $("#end_time").val();
245 if (!$.isNumeric(start_time)) {
248 if (!$.isNumeric(end_time)) {
253 var populateDict = function () {
255 dict['urltype'] = $(this).attr("class");
256 dict['id'] = $(this).attr("value");
258 dict['start_time'] = start_time;
259 dict['end_time'] = end_time;
260 devices[$(this).attr("alt")] = dict;
262 xaxis.each(populateDict);
263 yaxis.each(populateDict);
265 mctx.graph.xaxis = xaxis;
266 mctx.graph.yaxis = yaxis;
267 mctx.graph.start_time = start_time;
268 mctx.graph.end_time = end_time;
269 mctx.graph.devices = devices;
271 if (!mctx.graph.running) {
272 $("#graph-run").val("Pause");
273 $("#status-text").text("")
280 $.fn.runButton = function() {
281 if (mctx.graph.running) {
282 setGraphStatus(false);
283 clearTimeout(mctx.graph.timer);
285 $("#graph").setGraph();