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;
22 {'text' : 'Home', href : mctx.location + 'index.html'},
23 {'text' : 'Experiment control', href : mctx.location + 'control.html'},
24 {'text' : 'Pin debugging', href : mctx.location + 'pintest.html'},
25 {'text' : 'Help', href : mctx.location + 'help.html'}
32 mctx.statusCodesDescription = {
34 "-1" : "General error",
35 "-2" : "Unauthorized",
37 "-4" : "Already exists"
41 0 : {name : "Strain gauge 1"},
42 1 : {name : "Strain gauge 2"},
43 2 : {name : "Strain gauge 3"},
44 3 : {name : "Strain gauge 4"},
45 4 : {name : "Pressure sensor 1"},
46 5 : {name : "Pressure sensor 2"},
47 6 : {name : "Pressure sensor 3"}
51 0 : {name : "Solenoid 1"},
52 1 : {name : "Solenoid 2"},
53 2 : {name : "Solenoid 3"},
54 3 : {name : "Pressure regulator"}
57 mctx.strain_gauges = {};
58 mctx.strain_gauges.ids = [0, 1, 2, 3];
59 mctx.strain_gauges.time_limit = 20;
62 * Logs a message if mctx.debug is enabled. This function takes
63 * a variable number of arguments and passes them
64 * to alert or console.log (based on browser support).
65 * @returns {undefined}
67 function debugLog () {
69 if (typeof console === "undefined" || typeof console.log === "undefined") {
70 for (var i = 0; i < arguments.length; i++) {
75 console.log.apply(this, arguments);
78 for (var i = 0; i < arguments.length; i++) {
79 console.log(arguments[i]);
87 * Writes the current date to wherever it's called.
90 document.write((new Date()).toDateString());
94 * Should be run before the load of any GUI page.
95 * To hook events to be called after this function runs,
96 * use the 'always' method, e.g runBeforeLoad().always(function() {my stuff});
97 * @param {type} isLoginPage
98 * @returns The return value of calling $.ajax
100 function runBeforeLoad(isLoginPage) {
102 url : mctx.api + "identify"
103 }).done(function (data) {
104 if (data.logged_in && isLoginPage) {
106 debugLog("Redirect disabled!");
108 window.location = mctx.location;
110 } else if (!data.logged_in && !isLoginPage) {
112 debugLog("Redirect disabled!");
114 //Note: this only clears the nameless cookie
115 document.cookie = "";
116 window.location = mctx.location + "login.html";
119 mctx.friendlyName = data.friendly_name;
121 }).fail(function (jqHXR) {
123 debugLog("Failed to ident server. Is API running?")
124 } else if (!isLoginPage) {
125 window.location = mctx.location + "login.html";
127 }).always(function () {
133 * Populates the navigation menu.
135 $.fn.populateNavMenu = function() {
136 var root = $("<ul/>")
137 for (var i = 0; i < mctx.menu.length; i++) {
138 var item = mctx.menu[i];
139 var entry = $("<li/>").append(
140 $("<a/>", {text : item.text, href: item.href})
144 $(this).append(root);
149 * Sets the camera autoupdater
153 $.fn.setCamera = function () {
154 var url = mctx.api + "image"; //http://beaglebone/api/image
157 //Stop updating if we can't retrieve an image!
158 this.error(function() {
164 var updater = function() {
167 parent.attr("src", "");
171 parent.attr("src", url + "#" + (new Date()).getTime());
173 setTimeout(updater, 10000);
181 * Sets the strain graphs to graph stuff. Obsolete?
184 $.fn.setStrainGraphs = function () {
185 var sensor_url = mctx.api + "sensors";
188 var updater = function () {
189 var time_limit = mctx.strain_gauges.time_limit;
190 var responses = new Array(mctx.strain_gauges.ids.length);
192 for (var i = 0; i < mctx.strain_gauges.ids.length; i++) {
193 var parameters = {id : i, start_time: -time_limit};
194 responses[i] = $.ajax({url : sensor_url, data : parameters});
197 $.when.apply(this, responses).then(function () {
198 var data = new Array(arguments.length);
199 for (var i = 0; i < arguments.length; i++) {
200 var raw_data = arguments[i][0].data;
201 var pruned_data = [];
202 var step = ~~(raw_data.length/100);
203 for (var j = 0; j < raw_data.length; j += step)
204 pruned_data.push(raw_data[j]);
205 data[i] = pruned_data;
207 $.plot(graphdiv, data);
208 setTimeout(updater, 1000);
209 }, function () {debugLog("It crashed");});
217 * Performs a login attempt.
218 * @returns The AJAX object of the login request */
219 $.fn.login = function () {
220 var username = this.find("input[name='username']").val();
221 var password = this.find("input[name='pass']").val();
222 var out = this.find("#result");
223 var redirect = function () {
224 window.location.href = mctx.location;
227 out.removeAttr("class");
228 out.text("Logging in...");
231 url : mctx.api + "bind",
232 data : {user: username, pass : password}
233 }).done(function (data) {
234 if (data.status < 0) {
235 mctx.has_control = false;
236 out.attr("class", "fail");
237 out.text("Login failed: " + data.description);
240 mctx.has_control = true;
241 out.attr("class", "pass");
242 out.text("Login ok!");
243 setTimeout(redirect, 800);
245 }).fail(function (jqXHR) {
246 mctx.has_control = false;
247 out.attr("class", "fail");
248 out.text("Login request failed - connection issues.")
253 * Performs a logout request. The nameless cookie is
254 * always cleared and the browser redirected to the login page,
255 * independent of whether or not logout succeeded.
256 * @returns The AJAX object of the logout request.
258 $.fn.logout = function () {
260 url : mctx.api + "unbind"
261 }).always(function () {
262 //Note: this only clears the nameless cookie
263 document.cookie = "";
264 window.location = mctx.location + "login.html";
269 * Sets the error log to continuously update.
271 $.fn.setErrorLog = function () {
272 var url = mctx.api + "errorlog";
275 if ($(this).length <= 0) {
276 //No error log, so do nothing.
280 var updater = function () {
281 $.ajax({url : url}).done(function (data) {
284 outdiv[0].scrollHeight - outdiv.height()
286 setTimeout(updater, 3000);
287 }).fail(function (jqXHR) {
288 if (jqXHR.status === 502 || jqXHR.status === 0) {
289 outdiv.text("Failed to retrieve the error log.");
291 setTimeout(updater, 10000); //poll at slower rate
299 $(document).ready(function () {
301 $("#content").css("display", "block");
303 //Set the welcome bar
304 var name = " " + (mctx.friendlyName ? mctx.friendlyName : "");
305 $("#welcome-container").text("Welcome"+ name + "!");
306 $("#logout-container").css("display", "block");
307 //$("#menu-container").populateNavbar();
309 $("#logout").click(function () {
310 $("#logout").logout();
313 //Enable the error log, if present
314 $("#errorlog").setErrorLog();
316 //Enable the hide/show clicks
317 $("#sidebar-hide").click(function () {
318 $("#sidebar").css("display", "none");
319 $("#sidebar-show").css("display", "inherit");
323 $("#sidebar-show").click(function () {
324 $("#sidebar-show").css("display", "none");
325 $("#sidebar").css("display", "inherit");
329 $(document).ajaxError(function (event, jqXHR) {
330 //console.log("AJAX query failed with: " + jqXHR.status + " (" + jqXHR.statusText + ")");