Merge branch 'master' of https://github.com/szmoore/MCTX3420.git
[matches/MCTX3420.git] / testing / MCTXWeb / public_html / static / mctx.gui.js
1 /**
2  * MCTX3420 2013 GUI stuff.
3  */
4
5 mctx = {};
6 //Don't use this in the final version
7 mctx.location = window.location.pathname;
8 mctx.location = mctx.location.substring(0, mctx.location.lastIndexOf('/')) + "/";
9 //mctx.location = location.protocol + "//" + location.host + "/";
10 mctx.api = location.protocol + "//" + location.host + "/" + "api/";
11 mctx.expected_api_version = 0;
12 mctx.has_control = false;
13 //mctx.debug = true;
14
15 mctx.statusCodes = {
16   STATUS_OK : 1
17 }
18
19 mctx.statusCodesDescription = {
20   "1" : "Ok",
21   "-1" : "General error",
22   "-2" : "Unauthorized",
23   "-3" : "Not running",
24   "-4" : "Already exists"
25 };
26
27 mctx.sensors = {
28   0 : {name : "Strain gauge 1"},
29   1 : {name : "Strain gauge 2"},
30   2 : {name : "Strain gauge 3"},
31   3 : {name : "Strain gauge 4"},
32   4 : {name : "Pressure sensor 1"},
33   5 : {name : "Pressure sensor 2"},
34   6 : {name : "Pressure sensor 3"}
35 };
36
37 mctx.actuators = {
38   0 : {name : "Solenoid 1"},
39   1 : {name : "Solenoid 2"},
40   2 : {name : "Solenoid 3"},
41   3 : {name : "Pressure regulator"}
42 };
43
44 mctx.strain_gauges = {};
45 mctx.strain_gauges.ids = [0, 1, 2, 3];
46 mctx.strain_gauges.time_limit = 20;
47
48 function debugLog (msg) {
49   if (typeof console === "undefined" || typeof console.log === "undefined") {
50     alert(msg);
51   } else {
52     console.log(msg);
53   }
54 }
55
56 /**
57  * Writes the current date to wherever it's called.
58  */
59 function getDate(){
60         document.write((new Date()).toDateString());
61 }
62
63 /**
64  * Should be run before the load of any GUI page.
65  * To hook events to be called after this function runs,
66  * use the 'always' method, e.g runBeforeLoad().always(function() {my stuff});
67  * @param {type} isLoginPage
68  * @returns The return value of calling $.ajax
69  */
70 function runBeforeLoad(isLoginPage) {
71   return $.ajax({
72     url : mctx.api + "identify"
73   }).done(function (data) {
74     if (data.logged_in && isLoginPage) {
75       if (mctx.debug) {
76         debugLog("Redirect disabled!");
77       } else {
78         window.location = mctx.location;
79       }
80     } else if (!data.logged_in && !isLoginPage) {
81       if (mctx.debug) {
82         debugLog("Redirect disabled!");
83       } else {
84         //Note: this only clears the nameless cookie
85         document.cookie = ""; 
86         window.location = mctx.location + "login.html";
87       }
88     } else {
89       mctx.friendlyName = data.friendly_name;
90     }
91   }).fail(function (jqHXR) {
92     if (mctx.debug) {
93       debugLog("Failed to ident server. Is API running?")
94     } else if (!isLoginPage) {
95       window.location = mctx.location + "login.html";
96     }
97   });
98 }
99
100 /**
101  * Populates a submenu of the navigation bar
102  * @param {string} header The header
103  * @param {object} items An object representing the submenu items
104  * @param {function} translator A function that translates an object item
105  *                              into a text and href.
106  * @returns {$.fn} Itself
107  */
108 $.fn.populateSubmenu = function(header, items, translator) {
109   var submenuHeader = $("<li/>").append($("<a/>", {text : header, href : "#"}));
110   var submenu = $("<ul/>", {"class" : "submenu"});
111   
112   for (var item in items) {
113     var info = translator(item, items);
114     submenu.append($("<li/>").append(
115           $("<a/>", {text : info.text, 
116                      href : info.href, target : "_blank"})
117     ));
118   }
119   
120   this.append(submenuHeader.append(submenu));
121   return this;
122 };
123
124 /** 
125  * Populates the navigation bar
126  */
127 $.fn.populateNavbar = function () {
128   var menu = $("<ul/>", {"class" : "menu"});
129   var sensorTranslator = function(item, items) {
130     var href = mctx.api + "sensors?start_time=0&format=tsv&id=" + item;
131     return {text : items[item].name, href : href};
132   };
133   var actuatorTranslator = function(item, items) {
134     var href = mctx.api + "actuators?start_time=0&format=tsv&id=" + item;
135     return {text : items[item].name, href : href};
136   };
137   
138   menu.populateSubmenu("Sensor data", mctx.sensors, sensorTranslator);
139   menu.populateSubmenu("Actuator data", mctx.actuators, actuatorTranslator);
140   menu.appendTo(this);
141   return this;
142 }
143
144 /**
145  * Sets the camera autoupdater
146  * @returns {$.fn}
147  */
148 $.fn.setCamera = function () {
149   var url = mctx.api + "image";  //http://beaglebone/api/image
150   var update = true;
151
152   //Stop updating if we can't retrieve an image!
153   this.error(function() {
154     update = false;
155   });
156   
157   var parent = this;
158   
159   var updater = function() {
160     if (!update) {
161       alert("Cam fail");
162       parent.attr("src", "");
163       return;
164     }
165     
166     parent.attr("src", url + "#" + (new Date()).getTime());
167     
168     setTimeout(updater, 1000);
169   };
170   
171   updater();
172   return this;
173 };
174
175 $.fn.setStrainGraphs = function () {
176   var sensor_url = mctx.api + "sensors";
177   var graphdiv = this;
178   
179   var updater = function () {
180     var time_limit = mctx.strain_gauges.time_limit;
181     var responses = new Array(mctx.strain_gauges.ids.length);
182     
183     for (var i = 0; i < mctx.strain_gauges.ids.length; i++) {
184       var parameters = {id : i, start_time: -time_limit};
185       responses[i] = $.ajax({url : sensor_url, data : parameters});
186     }
187     
188     $.when.apply(this, responses).then(function () {
189       var data = new Array(arguments.length);
190       for (var i = 0; i < arguments.length; i++) {
191         var raw_data = arguments[i][0].data;
192         var pruned_data = [];
193         var step = ~~(raw_data.length/100);
194         for (var j = 0; j < raw_data.length; j += step)
195           pruned_data.push(raw_data[j]); 
196         data[i] = pruned_data;
197       }
198       $.plot(graphdiv, data);
199       setTimeout(updater, 500);
200     }, function () {alert("It crashed");});
201   };
202   
203   updater();
204   return this;
205 };
206
207 $.fn.login = function () {
208   var username = this.find("input[name='username']").val();
209   var password = this.find("input[name='pass']").val();
210   var out = this.find("#result");
211   var redirect = function () {
212     window.location.href = mctx.location;
213   };
214   
215   out.removeAttr("class");
216   out.text("Logging in...");
217   
218   $.ajax({
219     url : mctx.api + "bind",
220     data : {user: username, pass : password}
221   }).done(function (data) {
222     if (data.status < 0) {
223       mctx.has_control = false;
224       out.attr("class", "fail");
225       out.text("Login failed: " + data.description);
226     } else {
227       //todo: error check
228       mctx.has_control = true;
229       out.attr("class", "pass");
230       out.text("Login ok!");
231       setTimeout(redirect, 800);      
232     }
233   }).fail(function (jqXHR) {
234     mctx.has_control = false;
235     out.attr("class", "fail");
236     out.text("Login request failed - connection issues.")
237   });
238 };
239
240 $.fn.logout = function () {
241   $.ajax({
242     url : mctx.api + "unbind"
243   }).always(function () {
244     //Note: this only clears the nameless cookie
245     document.cookie = ""; 
246     window.location = mctx.location + "login.html";
247   });
248 }
249
250 $.fn.setErrorLog = function () {
251   var url = mctx.api + "errorlog";
252   var outdiv = this;
253   
254   var updater = function () {
255     $.ajax({url : url}).done(function (data) {
256       outdiv.text(data);
257       outdiv.scrollTop(
258         outdiv[0].scrollHeight - outdiv.height()
259       );
260       setTimeout(updater, 1000);
261     }).fail(function (jqXHR) {
262       if (jqXHR.status === 502 || jqXHR.status === 0) {
263         outdiv.text("Failed to retrieve the error log.");
264       }
265       setTimeout(updater, 1500);
266     });
267   };
268   
269   updater();
270 };
271
272 $(document).ajaxError(function (event, jqXHR) {
273   //console.log("AJAX query failed with: " + jqXHR.status + " (" + jqXHR.statusText + ")");
274 });

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