Fork of the espurna firmware for `mhsw` switches
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

287 lines
7.8 KiB

8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
  1. var websock;
  2. var password = false;
  3. function doUpdate() {
  4. var data = $("#formSave").serializeArray();
  5. websock.send(JSON.stringify({'config': data}));
  6. $(".powExpected").val(0);
  7. return false;
  8. }
  9. function doReset() {
  10. var response = window.confirm("Are you sure you want to reset the device?");
  11. if (response == false) return false;
  12. websock.send(JSON.stringify({'action': 'reset'}));
  13. return false;
  14. }
  15. function doReconnect() {
  16. var response = window.confirm("Are you sure you want to disconnect from the current WIFI network?");
  17. if (response == false) return false;
  18. websock.send(JSON.stringify({'action': 'reconnect'}));
  19. return false;
  20. }
  21. function doToggle(element, value) {
  22. var relayID = parseInt(element.attr("data"));
  23. websock.send(JSON.stringify({'action': value ? 'on' : 'off', 'relayID': relayID}));
  24. return false;
  25. }
  26. function randomString(length, chars) {
  27. var mask = '';
  28. if (chars.indexOf('a') > -1) mask += 'abcdefghijklmnopqrstuvwxyz';
  29. if (chars.indexOf('A') > -1) mask += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  30. if (chars.indexOf('#') > -1) mask += '0123456789';
  31. if (chars.indexOf('@') > -1) mask += 'ABCDEF';
  32. if (chars.indexOf('!') > -1) mask += '~`!@#$%^&*()_+-={}[]:";\'<>?,./|\\';
  33. var result = '';
  34. for (var i = length; i > 0; --i) result += mask[Math.round(Math.random() * (mask.length - 1))];
  35. return result;
  36. }
  37. function doGenerateAPIKey() {
  38. var apikey = randomString(16, '@#');
  39. $("input[name=\"apiKey\"]").val(apikey);
  40. return false;
  41. }
  42. function showPanel() {
  43. $(".panel").hide();
  44. $("#" + $(this).attr("data")).show();
  45. if ($("#layout").hasClass('active')) toggleMenu();
  46. $("input[type='checkbox']").iphoneStyle("calculateDimensions").iphoneStyle("refresh");
  47. };
  48. function toggleMenu() {
  49. $("#layout").toggleClass('active');
  50. $("#menu").toggleClass('active');
  51. $("#menuLink").toggleClass('active');
  52. }
  53. function createRelays(count) {
  54. var current = $("#relays > div").length;
  55. if (current > 0) return;
  56. var template = $("#relayTemplate .pure-g")[0];
  57. for (var relayID=0; relayID<count; relayID++) {
  58. var line = $(template).clone();
  59. $(line).find("input").each(function() {
  60. $(this).attr("data", relayID);
  61. });
  62. if (count > 1) $(".relay_id", line).html(" " + (relayID+1));
  63. line.appendTo("#relays");
  64. $(":checkbox", line).iphoneStyle({
  65. onChange: doToggle,
  66. resizeContainer: true,
  67. resizeHandle: true,
  68. checkedLabel: 'ON',
  69. uncheckedLabel: 'OFF'
  70. });
  71. }
  72. }
  73. function createIdxs(count) {
  74. var current = $("#idxs > div").length;
  75. if (current > 0) return;
  76. var template = $("#idxTemplate .pure-g")[0];
  77. for (var id=0; id<count; id++) {
  78. var line = $(template).clone();
  79. $(line).find("input").each(function() {
  80. $(this).attr("data", id).attr("tabindex", 43+id);
  81. });
  82. if (count > 1) $(".id", line).html(" " + id);
  83. line.appendTo("#idxs");
  84. }
  85. }
  86. function processData(data) {
  87. // title
  88. if ("app" in data) {
  89. var title = data.app;
  90. if ("version" in data) {
  91. title = title + " " + data.version;
  92. }
  93. $(".pure-menu-heading").html(title);
  94. if ("hostname" in data) {
  95. title = data.hostname + " - " + title;
  96. }
  97. document.title = title;
  98. }
  99. Object.keys(data).forEach(function(key) {
  100. // Actions
  101. if (key == "action") {
  102. if (data.action == "reload") {
  103. if (password) {
  104. // Forget current authentication
  105. $.ajax({
  106. 'method': 'GET',
  107. 'url': '/',
  108. 'async': false,
  109. 'username': "logmeout",
  110. 'password': "123456",
  111. 'headers': { "Authorization": "Basic xxx" }
  112. }).done(function(data) {
  113. // If we don't get an error, we actually got an error as we expect an 401!
  114. }).fail(function(){
  115. // We expect to get an 401 Unauthorized error! In this case we are successfully
  116. // logged out and we redirect the user.
  117. window.location = "/";
  118. });
  119. }
  120. }
  121. return;
  122. }
  123. // Wifi
  124. if (key == "wifi") {
  125. var groups = $("#panel-wifi .pure-g");
  126. for (var i in data.wifi) {
  127. var wifi = data.wifi[i];
  128. Object.keys(wifi).forEach(function(key) {
  129. var id = "input[name=" + key + "]";
  130. if ($(id, groups[i]).length) $(id, groups[i]).val(wifi[key]);
  131. });
  132. };
  133. return;
  134. }
  135. // Relay status
  136. if (key == "relayStatus") {
  137. var relays = data.relayStatus;
  138. createRelays(relays.length);
  139. for (var relayID in relays) {
  140. var element = $(".relayStatus[data=" + relayID + "]");
  141. if (element.length > 0) {
  142. element
  143. .prop("checked", relays[relayID])
  144. .iphoneStyle("refresh");
  145. }
  146. }
  147. return;
  148. }
  149. // Domoticz
  150. if (key == "dczIdx") {
  151. var idxs = data.dczIdx;
  152. createIdxs(idxs.length);
  153. for (var i in idxs) {
  154. var element = $(".dczIdx[data=" + i + "]");
  155. if (element.length > 0) element.val(idxs[i]);
  156. }
  157. return;
  158. }
  159. // Messages
  160. if (key == "message") {
  161. window.alert(data.message);
  162. return;
  163. }
  164. // Enable options
  165. if (key.endsWith("Visible")) {
  166. var module = key.slice(0,-7);
  167. console.log(module);
  168. $(".module-" + module).show();
  169. return;
  170. }
  171. // Pre-process
  172. if (key == "network") {
  173. data.network = data.network.toUpperCase();
  174. }
  175. if (key == "mqttStatus") {
  176. data.mqttStatus = data.mqttStatus ? "CONNECTED" : "NOT CONNECTED";
  177. }
  178. // Look for INPUTs
  179. var element = $("input[name=" + key + "]");
  180. if (element.length > 0) {
  181. if (element.attr('type') == 'checkbox') {
  182. element
  183. .prop("checked", data[key])
  184. .iphoneStyle("refresh");
  185. } else {
  186. element.val(data[key]);
  187. }
  188. return;
  189. }
  190. // Look for SELECTs
  191. var element = $("select[name=" + key + "]");
  192. if (element.length > 0) {
  193. element.val(data[key]);
  194. return;
  195. }
  196. });
  197. // Auto generate an APIKey if none defined yet
  198. if ($("input[name='apiKey']").val() == "") {
  199. doGenerateAPIKey();
  200. }
  201. }
  202. function getJson(str) {
  203. try {
  204. return JSON.parse(str);
  205. } catch (e) {
  206. return false;
  207. }
  208. }
  209. function initWebSocket(host) {
  210. if (host === undefined) {
  211. host = window.location.hostname;
  212. }
  213. websock = new WebSocket('ws://' + host + '/ws');
  214. websock.onopen = function(evt) {};
  215. websock.onclose = function(evt) {};
  216. websock.onerror = function(evt) {};
  217. websock.onmessage = function(evt) {
  218. var data = getJson(evt.data);
  219. if (data) processData(data);
  220. };
  221. }
  222. function init() {
  223. $("#menuLink").on('click', toggleMenu);
  224. $(".button-update").on('click', doUpdate);
  225. $(".button-reset").on('click', doReset);
  226. $(".button-reconnect").on('click', doReconnect);
  227. $(".button-apikey").on('click', doGenerateAPIKey);
  228. $(".pure-menu-link").on('click', showPanel);
  229. $.ajax({
  230. 'method': 'GET',
  231. 'url': '/auth'
  232. }).done(function(data) {
  233. initWebSocket();
  234. });
  235. }
  236. $(init);