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.

392 lines
19 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
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
8 years ago
8 years ago
8 years ago
8 years ago
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>ESPurna</title>
  5. <meta charset="utf-8" />
  6. <link rel="stylesheet" href="spectre.min.css" />
  7. <script src="jquery-1.12.3.min.js"></script>
  8. <style>
  9. html, body {
  10. font-size: 12px;
  11. margin: 0;
  12. padding: 0;
  13. width: 100%;
  14. height: 100%;
  15. }
  16. div.page {
  17. display: none;
  18. }
  19. .bg-grey {
  20. background-color: #efefef;
  21. padding: 1rem;
  22. border-radius: .3rem;
  23. }
  24. div.hint {
  25. background-color: #efefef;
  26. padding: 2rem;
  27. margin: 20px 0;
  28. border-left: 2px solid blue;
  29. }
  30. </style>
  31. <script>
  32. $(function() {
  33. var timer = null;
  34. $("form").submit(function(event) {
  35. button = $(":submit", this);
  36. button.addClass("loading");
  37. $.ajax({
  38. 'method': 'POST',
  39. 'url': '/save',
  40. 'dataType': 'json',
  41. 'data': $(this).serializeArray()
  42. }).done(function(data) {
  43. button.removeClass("loading");
  44. }).fail(function() {
  45. button.removeClass("loading");
  46. });
  47. event.preventDefault();
  48. setTimeout(update, 200);
  49. });
  50. function init() {
  51. $.ajax({
  52. 'method': 'GET',
  53. 'url': '/init',
  54. 'dataType': 'json'
  55. }).done(function(data) {
  56. keys = Object.keys(data);
  57. for (index in keys) {
  58. key = "#" + keys[index];
  59. value = data[keys[index]];
  60. try {
  61. if ($(key).prop('tagName') == 'INPUT') {
  62. $(key).val(value);
  63. } else {
  64. $(key).html(value);
  65. }
  66. } catch(err) {
  67. // nope
  68. };
  69. };
  70. timer = setInterval(update, data.updateInterval);
  71. document.title = data.hostname;
  72. $("[name='pwMainsVoltage']").val(data.pwMainsVoltage);
  73. $("[name='rfDevice']").val(data.rfDevice);
  74. });
  75. }
  76. function update() {
  77. $.ajax({
  78. 'method': 'GET',
  79. 'url': '/status',
  80. 'dataType': 'json'
  81. }).done(function(data) {
  82. $("#mqtt").val(data.mqtt ? "CONNECTED" : "NOT CONNECTED");
  83. $("#power").val((data.power | 0) + "W");
  84. $("#temperature").val((data.temperature | 0) + "ºC");
  85. $("#humidity").val((data.humidity | 0) + "%");
  86. if (data.relay) {
  87. $("#relay").addClass('btn-primary').html("ON");
  88. $("#status").val(1);
  89. } else {
  90. $("#relay").removeClass('btn-primary').html("OFF");
  91. $("#status").val(0);
  92. }
  93. });
  94. }
  95. $("#btn-admin").click(function() {
  96. $("#panel-status").hide();
  97. $("#panel-admin").show();
  98. $("#btn-admin").addClass('btn-primary');
  99. $("#btn-status").removeClass('btn-primary');
  100. });
  101. $("#btn-status").click(function() {
  102. $("#panel-admin").hide();
  103. $("#panel-status").show();
  104. $("#btn-admin").removeClass('btn-primary');
  105. $("#btn-status").addClass('btn-primary');
  106. });
  107. $("#relay").click(function(event) {
  108. var status = parseInt($("#status").val());
  109. if (status == 1) {
  110. $.ajax({'method': 'GET', 'url': '/relay/off'});
  111. } else {
  112. $.ajax({'method': 'GET', 'url': '/relay/on'});
  113. }
  114. setTimeout(update, 200);
  115. event.preventDefault();
  116. })
  117. init();
  118. update();
  119. });
  120. </script>
  121. </head>
  122. <body>
  123. <div class="container">
  124. <header class="navbar bg-grey">
  125. <section class="navbar-section">
  126. <a href="#" class="navbar-brand"><span id="appname"></span></a>
  127. </section>
  128. <section class="navbar-section">
  129. <button class="btn" id="btn-admin">Administration</button>
  130. <button class="btn btn-primary" id="btn-status">Status</button>
  131. </section>
  132. </header>
  133. <div class="page" id="panel-status" style="display: block;">
  134. <div class="columns">
  135. <div class="column col-12">
  136. <form class="form-horizontal">
  137. <div class="form-group">
  138. <div class="col-xs-3">
  139. <label class="form-label" for="manufacturer">Manufacturer</label>
  140. </div>
  141. <div class="col-xs-9">
  142. <input type="text" class="form-input" id="manufacturer" value="" disabled>
  143. </div>
  144. </div>
  145. <div class="form-group">
  146. <div class="col-xs-3">
  147. <label class="form-label" for="device">Device</label>
  148. </div>
  149. <div class="col-xs-9">
  150. <input type="text" class="form-input" id="device" value="" disabled>
  151. </div>
  152. </div>
  153. <div class="form-group">
  154. <div class="col-xs-3">
  155. <label class="form-label" for="hostname">Hostname</label>
  156. </div>
  157. <div class="col-xs-9">
  158. <input type="text" class="form-input" id="hostname" value="" disabled>
  159. </div>
  160. </div>
  161. <div class="form-group">
  162. <div class="col-xs-3">
  163. <label class="form-label" for="network">Network</label>
  164. </div>
  165. <div class="col-xs-9">
  166. <input type="text" class="form-input" id="network" value="" disabled>
  167. </div>
  168. </div>
  169. <div class="form-group">
  170. <div class="col-xs-3">
  171. <label class="form-label" for="ip">IP</label>
  172. </div>
  173. <div class="col-xs-9">
  174. <input type="text" class="form-input" id="ip" value="" disabled>
  175. </div>
  176. </div>
  177. <div class="form-group">
  178. <div class="col-xs-3">
  179. <label class="form-label" for="mqtt">MQTT Status</label>
  180. </div>
  181. <div class="col-xs-9">
  182. <input type="text" class="form-input" id="mqtt" disabled>
  183. </div>
  184. </div>
  185. <div class="form-group">
  186. <div class="col-xs-3">
  187. <label class="form-label" for="power">Power</label>
  188. </div>
  189. <div class="col-xs-6">
  190. <input type="text" class="form-input" id="power" disabled>
  191. </div>
  192. </div>
  193. <div class="form-group">
  194. <div class="col-xs-3">
  195. <label class="form-label" for="temperature">Temperature</label>
  196. </div>
  197. <div class="col-xs-6">
  198. <input type="text" class="form-input" id="temperature" disabled>
  199. </div>
  200. </div>
  201. <div class="form-group">
  202. <div class="col-xs-3">
  203. <label class="form-label" for="humidity">Humidity</label>
  204. </div>
  205. <div class="col-xs-6">
  206. <input type="text" class="form-input" id="humidity" disabled>
  207. </div>
  208. </div>
  209. <div class="form-group">
  210. <div class="col-xs-3">
  211. <label class="form-label" for="relay">Relay Status</label>
  212. </div>
  213. <div class="col-xs-6">
  214. <input type="hidden" class="form-input" name="status" id="status" value="0" />
  215. <a class="btn" data="0" id="relay">OFF</a>
  216. </div>
  217. </div>
  218. </form>
  219. </div>
  220. </div>
  221. </div>
  222. <div class="page" id="panel-admin">
  223. <form action="/" method="post">
  224. <div class="hint">
  225. You can configure up to 3 different WiFi networks. The device will try to connect to any of them starting with the first one.
  226. </div>
  227. <div class="columns">
  228. <div class="column col-4">
  229. <h5>Network 1</h5>
  230. <div class="form-group">
  231. <label class="form-label" for="ssid0">Network SSID</label>
  232. <input name="ssid0" id="ssid0" type="text" class="form-input" size="8" tabindex="1" placeholder="Network SSID">
  233. </div>
  234. <div>
  235. <label class="form-label" for="pass0">Network Password</label>
  236. <input name="pass0" id="pass0" type="text" class="form-input" maxlength="255" tabindex="2" placeholder="Network password">
  237. </div>
  238. </div>
  239. <div class="column col-4">
  240. <h5>Network 2</h5>
  241. <div class="form-group">
  242. <label class="form-label" for="ssid1">Network SSID</label>
  243. <input name="ssid1" id="ssid1" type="text" class="form-input" size="8" tabindex="3" placeholder="Network SSID">
  244. </div>
  245. <div>
  246. <label class="form-label" for="pass1">Network Password</label>
  247. <input name="pass1" id="pass1" type="text" class="form-input" maxlength="255" tabindex="4" placeholder="Network password">
  248. </div>
  249. </div>
  250. <div class="column col-4">
  251. <h5>Network 3</h5>
  252. <div class="form-group">
  253. <label class="form-label" for="ssid2">Network SSID</label>
  254. <input name="ssid2" id="ssid2" type="text" class="form-input" size="8" tabindex="5" placeholder="Network SSID">
  255. </div>
  256. <div>
  257. <label class="form-label" for="pass2">Network Password</label>
  258. <input name="pass2" id="pass2" type="text" class="form-input" maxlength="255" tabindex="6" placeholder="Network password">
  259. </div>
  260. </div>
  261. </div>
  262. <div class="clearfix"></div>
  263. <div class="hint">
  264. Configure an <strong>MQTT broker</strong> in your network and you will be able to change the switch status via an MQTT message. Just send a 0 or a 1 as a payload to the provided topic below.
  265. The switch will also report its current open/close status to the same topic and its IP address to the topic you define plus "<code>/ip</code>". Leave the server field empty to disable MQTT.
  266. </div>
  267. <div class="columns">
  268. <div class="column col-4">
  269. <div class="form-group">
  270. <label class="form-label" for="mqttServer">MQTT Server</label>
  271. <input name="mqttServer" id="mqttServer" type="text" class="form-input" size="8" tabindex="8" placeholder="MQTT Server">
  272. </div>
  273. </div>
  274. <div class="column col-2">
  275. <div class="form-group">
  276. <label class="form-label" for="mqttPort">MQTT Port</label>
  277. <input name="mqttPort" id="mqttPort" type="text" class="form-input" size="8" tabindex="9" placeholder="1883">
  278. </div>
  279. </div>
  280. </div>
  281. <div class="columns">
  282. <div class="column col-4">
  283. <div class="form-group">
  284. <label class="form-label" for="mqttUser">MQTT User</label>
  285. <input name="mqttUser" id="mqttUser" type="text" class="form-input" size="8" tabindex="10" placeholder="Leave blank if no user/pass">
  286. </div>
  287. </div>
  288. <div class="column col-4">
  289. <div class="form-group">
  290. <label class="form-label" for="mqttPassword">MQTT Password</label>
  291. <input name="mqttPassword" id="mqttPassword" type="text" class="form-input" size="8" tabindex="11" placeholder="Leave blank if no user/pass">
  292. </div>
  293. </div>
  294. </div>
  295. <div class="columns">
  296. <div class="column col-4">
  297. <div class="form-group">
  298. <label class="form-label" for="mqttTopic">MQTT Topic</label>
  299. <input name="mqttTopic" id="mqttTopic" type="text" class="form-input" size="8" tabindex="12" maxlength="35" placeholder="MQTT Topic">
  300. </div>
  301. </div>
  302. </div>
  303. <div class="clearfix"></div>
  304. <div class="hint">
  305. If your device supports RF switching you can configure here the channel and device ID.
  306. </div>
  307. <div class="columns">
  308. <div class="column col-2">
  309. <div class="form-group">
  310. <label class="form-label" for="rfChannel">RF Channel</label>
  311. <input name="rfChannel" id="rfChannel" type="number" min="0" max="31" step="1" class="form-input" tabindex="13"/>
  312. </div>
  313. </div>
  314. <div class="column col-2">
  315. <div class="form-group">
  316. <label class="form-label" for="rfDevice">RF Device</label>
  317. <select name="rfDevice" class="form-input" tabindex="14">
  318. <option value="0">A</a>
  319. <option value="1">B</a>
  320. <option value="2">C</a>
  321. <option value="3">D</a>
  322. <option value="4">E</a>
  323. </select>
  324. </div>
  325. </div>
  326. </div>
  327. <div class="clearfix"></div>
  328. <div class="hint">
  329. If your device supports power measurement, here you can configure line potential and current ratio.
  330. </div>
  331. <div class="columns">
  332. <div class="column col-2">
  333. <div class="form-group">
  334. <label class="form-label" for="pwMainsVoltage">AC RMS Voltage</label>
  335. <select name="pwMainsVoltage" class="form-input" tabindex="15">
  336. <option value="125">125</a>
  337. <option value="220">220</a>
  338. <option value="230">230</a>
  339. <option value="240">240</a>
  340. </select>
  341. </div>
  342. </div>
  343. <div class="column col-2">
  344. <div class="form-group">
  345. <label class="form-label" for="pwCurrentRatio">Current ratio</label>
  346. <input name="pwCurrentRatio" id="pwCurrentRatio" type="text" class="form-input" size="8" tabindex="16" placeholder="30">
  347. </div>
  348. </div>
  349. </div>
  350. <div>
  351. <div>
  352. <button class="btn btn-primary float-right">Update</button>
  353. </div>
  354. </div>
  355. </form>
  356. </div>
  357. </div>
  358. </body>
  359. </html>