Rename help/data file + fix the sidebar width
[matches/MCTX3420.git] / testing / MCTXWeb / public_html / static / mctx.gui.js
1 /**
2 * MCTX3420 2013 GUI stuff.
3 * Coding style:
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
9 */
10
11 mctx = {};
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;
19 mctx.debug = true;
20
21 mctx.menu = [
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'}
26 ];
27
28 mctx.statusCodes = {
29     STATUS_OK : 1
30 };
31
32 mctx.statusCodesDescription = {
33     "1" : "Ok",
34     "-1" : "General error",
35     "-2" : "Unauthorized",
36     "-3" : "Not running",
37     "-4" : "Already exists"
38 };
39
40 mctx.sensors = {
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"}
48 };
49
50 mctx.actuators = {
51     0 : {name : "Solenoid 1"},
52     1 : {name : "Solenoid 2"},
53     2 : {name : "Solenoid 3"},
54     3 : {name : "Pressure regulator"}
55 };
56
57 mctx.strain_gauges = {};
58 mctx.strain_gauges.ids = [0, 1, 2, 3];
59 mctx.strain_gauges.time_limit = 20;
60
61 /**
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}
66 */
67 function debugLog () {
68     if (mctx.debug) {
69         if (typeof console === "undefined" || typeof console.log === "undefined") {
70             for (var i = 0; i < arguments.length; i++) {
71                 alert(arguments[i]);
72             }
73         } else {
74             console.log.apply(this, arguments);
75         }
76     }
77 }
78
79 /**
80 * Writes the current date to wherever it's called.
81 */
82 function getDate() {
83     document.write((new Date()).toDateString());
84 }
85
86 /**
87 * Should be run before the load of any GUI page.
88 * To hook events to be called after this function runs,
89 * use the 'always' method, e.g runBeforeLoad().always(function() {my stuff});
90 * @param {type} isLoginPage
91 * @returns The return value of calling $.ajax
92 */
93 function runBeforeLoad(isLoginPage) {
94     return $.ajax({
95         url : mctx.api + "identify"
96     }).done(function (data) {
97         if (data.logged_in && isLoginPage) {
98             if (mctx.debug) {
99                 debugLog("Redirect disabled!");
100             } else {
101                 window.location = mctx.location;
102             }
103         } else if (!data.logged_in && !isLoginPage) {
104             if (mctx.debug) {
105                 debugLog("Redirect disabled!");
106             } else {
107                 //Note: this only clears the nameless cookie
108                 document.cookie = ""; 
109                 window.location = mctx.location + "login.html";
110             }
111         } else {
112             mctx.friendlyName = data.friendly_name;
113         }
114     }).fail(function (jqHXR) {
115         if (mctx.debug) {
116             debugLog("Failed to ident server. Is API running?")
117         } else if (!isLoginPage) {
118             window.location = mctx.location + "login.html";
119         }
120     }).always(function () {
121         
122     });
123 }
124
125 /**
126  * Populates the navigation menu.
127  */
128 $.fn.populateNavMenu = function() {
129     var root = $("<ul/>")
130     for (var i = 0; i < mctx.menu.length; i++) {
131         var item = mctx.menu[i];
132         var entry = $("<li/>").append(
133             $("<a/>", {text : item.text, href: item.href})
134         );
135         root.append(entry);
136     }
137     $(this).append(root);
138     return this;
139 }
140
141 /**
142 * Sets the camera autoupdater
143 * Obsolete?
144 * @returns {$.fn}
145 */
146 $.fn.setCamera = function () {
147     var url = mctx.api + "image";  //http://beaglebone/api/image
148     var update = true;
149
150     //Stop updating if we can't retrieve an image!
151     this.error(function() {
152         update = false;
153     });
154
155     var parent = this;
156
157     var updater = function() {
158         if (!update) {
159             alert("Cam fail");
160             parent.attr("src", "");
161             return;
162         }
163         
164         parent.attr("src", url + "#" + (new Date()).getTime());
165         
166         setTimeout(updater, 10000);
167     };
168
169     updater();
170     return this;
171 };
172
173 /**
174 * Sets the strain graphs to graph stuff. Obsolete?
175 * @returns {$.fn}
176 */
177 $.fn.setStrainGraphs = function () {
178     var sensor_url = mctx.api + "sensors";
179     var graphdiv = this;
180
181     var updater = function () {
182         var time_limit = mctx.strain_gauges.time_limit;
183         var responses = new Array(mctx.strain_gauges.ids.length);
184         
185         for (var i = 0; i < mctx.strain_gauges.ids.length; i++) {
186             var parameters = {id : i, start_time: -time_limit};
187             responses[i] = $.ajax({url : sensor_url, data : parameters});
188         }
189         
190         $.when.apply(this, responses).then(function () {
191             var data = new Array(arguments.length);
192             for (var i = 0; i < arguments.length; i++) {
193                 var raw_data = arguments[i][0].data;
194                 var pruned_data = [];
195                 var step = ~~(raw_data.length/100);
196                 for (var j = 0; j < raw_data.length; j += step)
197                 pruned_data.push(raw_data[j]); 
198                 data[i] = pruned_data;
199             }
200             $.plot(graphdiv, data);
201             setTimeout(updater, 1000);
202         }, function () {debugLog("It crashed");});
203     };
204
205     updater();
206     return this;
207 };
208
209 /**
210 * Performs a login attempt.
211 * @returns The AJAX object of the login request */
212 $.fn.login = function () {
213     var username = this.find("input[name='username']").val();
214     var password = this.find("input[name='pass']").val();
215     var out = this.find("#result");
216     var redirect = function () {
217         window.location.href = mctx.location;
218     };
219
220     out.removeAttr("class");
221     out.text("Logging in...");
222
223     return $.ajax({
224         url : mctx.api + "bind",
225         data : {user: username, pass : password}
226     }).done(function (data) {
227         if (data.status < 0) {
228             mctx.has_control = false;
229             out.attr("class", "fail");
230             out.text("Login failed: " + data.description);
231         } else {
232             //todo: error check
233             mctx.has_control = true;
234             out.attr("class", "pass");
235             out.text("Login ok!");
236             setTimeout(redirect, 800);      
237         }
238     }).fail(function (jqXHR) {
239         mctx.has_control = false;
240         out.attr("class", "fail");
241         out.text("Login request failed - connection issues.")
242     });
243 };
244
245 /**
246 * Performs a logout request. The nameless cookie is
247 * always cleared and the browser redirected to the login page,
248 * independent of whether or not logout succeeded.
249 * @returns  The AJAX object of the logout request.
250 */
251 $.fn.logout = function () {
252     return $.ajax({
253         url : mctx.api + "unbind"
254     }).always(function () {
255         //Note: this only clears the nameless cookie
256         document.cookie = ""; 
257         window.location = mctx.location + "login.html";
258     });
259 };
260
261 /**
262 * Sets the error log to continuously update.
263 * @returns itself */
264 $.fn.setErrorLog = function () {
265     var url = mctx.api + "errorlog";
266     var outdiv = this;
267
268     var updater = function () {
269         $.ajax({url : url}).done(function (data) {
270             outdiv.text(data);
271             outdiv.scrollTop(
272             outdiv[0].scrollHeight - outdiv.height()
273             );
274             setTimeout(updater, 3000);
275         }).fail(function (jqXHR) {
276             if (jqXHR.status === 502 || jqXHR.status === 0) {
277                 outdiv.text("Failed to retrieve the error log.");
278             }
279             setTimeout(updater, 10000); //poll at slower rate
280         });
281     };
282
283     updater();
284     return this;
285 };
286
287 $(document).ajaxError(function (event, jqXHR) {
288     //console.log("AJAX query failed with: " + jqXHR.status + " (" + jqXHR.statusText + ")");
289 });

UCC git Repository :: git.ucc.asn.au