2 * MCTX3420 2013 GUI stuff.
4 * - Always end statements with semicolons
5 * - Egyptian brackets are highly recommended (*cough*).
6 * - Don't use synchronous stuff - hook events into callbacks
7 * - $.fn functions should return either themselves or some useful object
8 * to allow for chaining of method calls
12 //Don't use this in the final version
13 mctx.location = window.location.pathname;
14 mctx.location = mctx.location.substring(0, mctx.location.lastIndexOf('/')) + "/";
15 //mctx.location = location.protocol + "//" + location.host + "/";
16 mctx.api = location.protocol + "//" + location.host + "/" + "api/";
17 mctx.expected_api_version = 0;
18 mctx.has_control = false;
25 mctx.statusCodesDescription = {
27 "-1" : "General error",
28 "-2" : "Unauthorized",
30 "-4" : "Already exists"
34 0 : {name : "Strain gauge 1"},
35 1 : {name : "Strain gauge 2"},
36 2 : {name : "Strain gauge 3"},
37 3 : {name : "Strain gauge 4"},
38 4 : {name : "Pressure sensor 1"},
39 5 : {name : "Pressure sensor 2"},
40 6 : {name : "Pressure sensor 3"}
44 0 : {name : "Solenoid 1"},
45 1 : {name : "Solenoid 2"},
46 2 : {name : "Solenoid 3"},
47 3 : {name : "Pressure regulator"}
50 mctx.strain_gauges = {};
51 mctx.strain_gauges.ids = [0, 1, 2, 3];
52 mctx.strain_gauges.time_limit = 20;
55 * Logs a message if mctx.debug is enabled. This function takes
56 * a variable number of arguments and passes them
57 * to alert or console.log (based on browser support).
58 * @returns {undefined}
60 function debugLog () {
62 if (typeof console === "undefined" || typeof console.log === "undefined") {
63 for (var i = 0; i < arguments.length; i++) {
67 console.log.apply(this, arguments);
73 * Writes the current date to wherever it's called.
76 document.write((new Date()).toDateString());
80 * Should be run before the load of any GUI page.
81 * To hook events to be called after this function runs,
82 * use the 'always' method, e.g runBeforeLoad().always(function() {my stuff});
83 * @param {type} isLoginPage
84 * @returns The return value of calling $.ajax
86 function runBeforeLoad(isLoginPage) {
88 url : mctx.api + "identify"
89 }).done(function (data) {
90 if (data.logged_in && isLoginPage) {
92 debugLog("Redirect disabled!");
94 window.location = mctx.location;
96 } else if (!data.logged_in && !isLoginPage) {
98 debugLog("Redirect disabled!");
100 //Note: this only clears the nameless cookie
101 document.cookie = "";
102 window.location = mctx.location + "login.html";
105 mctx.friendlyName = data.friendly_name;
107 }).fail(function (jqHXR) {
109 debugLog("Failed to ident server. Is API running?")
110 } else if (!isLoginPage) {
111 window.location = mctx.location + "login.html";
117 * Populates a submenu of the navigation bar
118 * @param {string} header The header
119 * @param {object} items An object representing the submenu items
120 * @param {function} translator A function that translates an object item
121 * into a text and href.
122 * @returns {$.fn} Itself
124 $.fn.populateSubmenu = function(header, items, translator) {
125 var submenuHeader = $("<li/>").append($("<a/>", {text : header, href : "#"}));
126 var submenu = $("<ul/>", {"class" : "submenu"});
128 for (var item in items) {
129 var info = translator(item, items);
130 submenu.append($("<li/>").append(
131 $("<a/>", {text : info.text,
132 href : info.href, target : "_blank"})
136 this.append(submenuHeader.append(submenu));
141 * Populates the navigation bar
143 $.fn.populateNavbar = function () {
144 var menu = $("<ul/>", {"class" : "menu"});
145 var sensorTranslator = function(item, items) {
146 var href = mctx.api + "sensors?start_time=0&format=tsv&id=" + item;
147 return {text : items[item].name, href : href};
149 var actuatorTranslator = function(item, items) {
150 var href = mctx.api + "actuators?start_time=0&format=tsv&id=" + item;
151 return {text : items[item].name, href : href};
154 menu.populateSubmenu("Sensor data", mctx.sensors, sensorTranslator);
155 menu.populateSubmenu("Actuator data", mctx.actuators, actuatorTranslator);
161 * Sets the camera autoupdater
165 $.fn.setCamera = function () {
166 var url = mctx.api + "image"; //http://beaglebone/api/image
169 //Stop updating if we can't retrieve an image!
170 this.error(function() {
176 var updater = function() {
179 parent.attr("src", "");
183 parent.attr("src", url + "#" + (new Date()).getTime());
185 setTimeout(updater, 1000);
193 * Sets the strain graphs to graph stuff. Obsolete?
196 $.fn.setStrainGraphs = function () {
197 var sensor_url = mctx.api + "sensors";
200 var updater = function () {
201 var time_limit = mctx.strain_gauges.time_limit;
202 var responses = new Array(mctx.strain_gauges.ids.length);
204 for (var i = 0; i < mctx.strain_gauges.ids.length; i++) {
205 var parameters = {id : i, start_time: -time_limit};
206 responses[i] = $.ajax({url : sensor_url, data : parameters});
209 $.when.apply(this, responses).then(function () {
210 var data = new Array(arguments.length);
211 for (var i = 0; i < arguments.length; i++) {
212 var raw_data = arguments[i][0].data;
213 var pruned_data = [];
214 var step = ~~(raw_data.length/100);
215 for (var j = 0; j < raw_data.length; j += step)
216 pruned_data.push(raw_data[j]);
217 data[i] = pruned_data;
219 $.plot(graphdiv, data);
220 setTimeout(updater, 500);
221 }, function () {debugLog("It crashed");});
229 * Performs a login attempt.
230 * @returns The AJAX object of the login request */
231 $.fn.login = function () {
232 var username = this.find("input[name='username']").val();
233 var password = this.find("input[name='pass']").val();
234 var out = this.find("#result");
235 var redirect = function () {
236 window.location.href = mctx.location;
239 out.removeAttr("class");
240 out.text("Logging in...");
243 url : mctx.api + "bind",
244 data : {user: username, pass : password}
245 }).done(function (data) {
246 if (data.status < 0) {
247 mctx.has_control = false;
248 out.attr("class", "fail");
249 out.text("Login failed: " + data.description);
252 mctx.has_control = true;
253 out.attr("class", "pass");
254 out.text("Login ok!");
255 setTimeout(redirect, 800);
257 }).fail(function (jqXHR) {
258 mctx.has_control = false;
259 out.attr("class", "fail");
260 out.text("Login request failed - connection issues.")
265 * Performs a logout request. The nameless cookie is
266 * always cleared and the browser redirected to the login page,
267 * independent of whether or not logout succeeded.
268 * @returns The AJAX object of the logout request.
270 $.fn.logout = function () {
272 url : mctx.api + "unbind"
273 }).always(function () {
274 //Note: this only clears the nameless cookie
275 document.cookie = "";
276 window.location = mctx.location + "login.html";
281 * Sets the error log to continuously update.
283 $.fn.setErrorLog = function () {
284 var url = mctx.api + "errorlog";
287 var updater = function () {
288 $.ajax({url : url}).done(function (data) {
291 outdiv[0].scrollHeight - outdiv.height()
293 setTimeout(updater, 2000);
294 }).fail(function (jqXHR) {
295 if (jqXHR.status === 502 || jqXHR.status === 0) {
296 outdiv.text("Failed to retrieve the error log.");
298 setTimeout(updater, 4000);
306 $(document).ajaxError(function (event, jqXHR) {
307 //console.log("AJAX query failed with: " + jqXHR.status + " (" + jqXHR.statusText + ")");