httpServer.ino 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874
  1. //extern ESP8266WebServer httpServer;
  2. static const char httpRoot[] PROGMEM =
  3. R"(<html><body>
  4. <h1><span id='devname'></span></h1>
  5. <h3>WiFi Switch</h3>
  6. <form id='BtnFrm1'><input type='hidden' name='Btn1' value='1'></form>
  7. <form id='BtnFrm2'><input type='hidden' name='Btn2' value='1'></form>
  8. <form id='BtnFrm3'><input type='hidden' name='Btn3' value='1'></form>
  9. <form id='AllOnFrm'><input type='hidden' name='allOn' value='1'></form>
  10. <form id='AllOffFrm'><input type='hidden' name='allOff' value='1'></form>
  11. <input type='button' value='All ON' id='allOn' onclick='return sendAllOn()'/><input type='button' value='All OFF' id='allOff' onclick='return sendAllOff()'/>
  12. <div style='font-size:xx-large'>
  13. <div id='sw1div' style='display:none'>1: <input type='button' id='tbtn1' onclick='return sendBtn(1)'/><br></div>
  14. <div id='sw2div' style='display:none'>2: <input type='button' id='tbtn2' onclick='return sendBtn(2)'/><br></div>
  15. <div id='sw3div' style='display:none'>3: <input type='button' id='tbtn3' onclick='return sendBtn(3)'/><br></div>
  16. </div>
  17. <br>
  18. <br>
  19. WiFi connected to <i><span id='ssid'></span></i>.<br>
  20. <h6>Last update
  21. <span id='ut'></span> seconds ago.
  22. <span id='status'></span>
  23. </h6>
  24. <br>
  25. <a href='/wifi.htm'>WiFi settings</a><br>
  26. <a href='/confhw'>Hardware configuration</a><br>
  27. <a href='/conf'>Base configuration</a><br>
  28. <a href='/conf2'>Extended configuration</a><br>
  29. <a href='/update'>Firmware update</a><br>
  30. <a href='/restart'>Restart</a>
  31. <script>
  32. function g(i) { return document.getElementById(i) };
  33. var xhttp, updateTime, reqTime, reqFin;
  34. var textA = 'OFF';
  35. var textE = 'ON';
  36. function sendBtn(btn) {
  37. var frmn='BtnFrm'+btn;
  38. var form = g(frmn);
  39. return transmit(form);
  40. }
  41. function sendAllOn() {
  42. return transmit(g('AllOnFrm'));
  43. }
  44. function sendAllOff() {
  45. return transmit(g('AllOffFrm'));
  46. }
  47. function transmit(f) {
  48. if (!xhttp) {
  49. g('status').innerHTML = 'loading...';
  50. reqTime = 0;
  51. reqFin = false;
  52. xhttp = new XMLHttpRequest();
  53. xhttp.timeout = 2000;
  54. xhttp.open('POST', 'api');
  55. xhttp.send(f ? (new FormData(f)) : '');
  56. xhttp.onreadystatechange = function () {
  57. if (xhttp.readyState === XMLHttpRequest.DONE && xhttp.status === 200) {
  58. var data = JSON.parse(xhttp.responseText);
  59. g('ssid').innerHTML = data.ssid;
  60. if(data.devname != undefined) g('devname').innerHTML = data.devname;
  61. if(data.swState1 != undefined) g('sw1div').style.display='inline';
  62. else g('sw1div').style.display='none';
  63. if(data.swState2 != undefined) g('sw2div').style.display='inline';
  64. else g('sw2div').style.display='none';
  65. if(data.swState3 != undefined) g('sw3div').style.display='inline';
  66. else g('sw3div').style.display='none';
  67. if(data.swState1 == '1') g('tbtn1').value = textE;
  68. else g('tbtn1').value = textA;
  69. if(data.swState2 == '1') g('tbtn2').value = textE;
  70. else g('tbtn2').value = textA;
  71. if(data.swState3 == '1') g('tbtn3').value = textE;
  72. else g('tbtn3').value = textA;
  73. xhttp = null;
  74. updateTime = 0;
  75. reqFin = true;
  76. }
  77. else {
  78. if(!reqFin && reqTime > 10) {
  79. xhttp = null;
  80. reqFin = true;
  81. }
  82. }
  83. }
  84. }
  85. return false;
  86. }
  87. transmit();
  88. setInterval(function () { g('ut').innerHTML = ++updateTime; ++reqTime; }, 1000);
  89. setInterval(transmit, 5000);
  90. </script>
  91. </body></html>)";
  92. static const char httpConfPage[] PROGMEM =
  93. R"(<html><head><body>
  94. <h3>Base configuration</h3>
  95. <a href='/'>Home</a><br><br>
  96. <input type='button' value='reload' onclick='return transmit()'/><br><br>
  97. <form id='form1' onsubmit='return transmit(this)'>
  98. Device Name: <input type='text' name='devName' id='devName'/><br><br>
  99. HTTP User *: <input type='text' name='httpUser' id='httpUser'/><br>
  100. HTTP Password *: <input type='text' name='httpPass' id='httpPass'/><br><br>
  101. MQTT Server *: <input type='text' name='mqttHost' id='mqttHost'/><br>
  102. MQTT Port *: <input type='number' name='mqttPort' id='mqttPort'/><br>
  103. MQTT User *: <input type='text' name='mqttUser' id='mqttUser'/><br>
  104. MQTT Password *: <input type='text' name='mqttPass' id='mqttPass'/><br><br>
  105. In Topic *: <input type='text' name='inTop' id='inTop'/><br>
  106. Out Topic: <input type='text' name='outTop' id='outTop'/><br>
  107. Out Retain *: <input type='checkbox' name='outRet' id='outRet'/><br><br>
  108. LastWill Topic *: <input type='text' name='willTop' id='willTop'/><br>
  109. LastWill Qos *: <select name='willQos' id='willQos'><option>0</option><option>1</option><option>2</option></select><br>
  110. LastWill Retain *: <input type='checkbox' name='willRet' id='willRet'/><br>
  111. LastWill Message *: <input type='text' name='willMsg' id='willMsg'/><br><br>
  112. Domoticz Out Topic *: <input type='text' name='domOutTop' id='domOutTop'/><br><br>
  113. All ON/OFF Topic *: <input type='text' name='allOnOffTop' id='allOnOffTop'/><br>
  114. <br>
  115. <input type='submit' value='Save'/>
  116. </form>
  117. <form id='restartForm' onsubmit='return res()'>
  118. <input type='hidden' name='restart' value='1'>
  119. <input type='submit' value='Restart'/>
  120. </form>
  121. <script>
  122. function g(i) { return document.getElementById(i) };
  123. var xhttp, reqTime, reqFin, rxhttp;
  124. function res() {
  125. rxhttp = new XMLHttpRequest();
  126. rxhttp.timeout = 1000;
  127. rxhttp.open('POST', 'restart');
  128. rxhttp.send('');
  129. rxhttp = null;
  130. return false;
  131. }
  132. function setCheckbox(ele, dat) {
  133. if(dat == 1) {
  134. ele.checked = true;
  135. ele.style.visibility = 'visible';
  136. }
  137. else {
  138. ele.checked = false;
  139. ele.style.visibility = 'visible';
  140. }
  141. }
  142. function updateCheckboxValue(ele) {
  143. if (ele.checked) ele.value ='1';
  144. else {
  145. ele.value = '0';
  146. ele.checked = true;
  147. ele.style.visibility = 'hidden';
  148. }
  149. }
  150. function transmit(f) {
  151. if (!xhttp) {
  152. reqTime = 0;
  153. reqFin = false;
  154. updateCheckboxValue(g('outRet'));
  155. updateCheckboxValue(g('willRet'));
  156. xhttp = new XMLHttpRequest();
  157. xhttp.timeout = 2000;
  158. xhttp.open('POST', 'confdata');
  159. xhttp.send(f ? (new FormData(f)) : '');
  160. xhttp.onreadystatechange = function () {
  161. if (xhttp.readyState === XMLHttpRequest.DONE && xhttp.status === 200) {
  162. var data = JSON.parse(xhttp.responseText);
  163. g('httpUser').value = data.httpUser;
  164. g('httpPass').value = data.httpPass;
  165. g('devName').value = data.devName
  166. g('mqttHost').value = data.mqttHost;
  167. g('mqttPort').value = data.mqttPort;
  168. g('mqttUser').value = data.mqttUser;
  169. g('mqttPass').value = data.mqttPass;
  170. g('inTop').value = data.inTop;
  171. g('outTop').value = data.outTop;
  172. g('willTop').value = data.willTop;
  173. g('willQos').value = data.willQos;
  174. setCheckbox(g('outRet'), data.outRet);
  175. setCheckbox(g('willRet'), data.willRet);
  176. g('willMsg').value = data.willMsg;
  177. g('domOutTop').value = data.domOutTop;
  178. g('allOnOffTop').value = data.allOnOffTop;
  179. xhttp = null;
  180. reqFin = true;
  181. }
  182. else {
  183. if(!reqFin && reqTime > 10) {
  184. xhttp = null;
  185. reqFin = true;
  186. }
  187. }
  188. }
  189. }
  190. return false;
  191. }
  192. transmit();
  193. setInterval(function () { ++reqTime; }, 1000);
  194. </script>
  195. </body></html>)"; //httpConfPage
  196. static const char httpConf2Page[] PROGMEM =
  197. R"(<html><head><body>
  198. <h3>Extended configuration</h3>
  199. <a href='/'>Home</a><br><br>
  200. <input type='button' value='reload' onclick='return transmit()'/><br>
  201. <form id='form1' onsubmit='return transmit(this)'>
  202. <h4>Domoticz</h4>
  203. Domoticz Idx 1: <input type='number' name='domIdx1' id='domIdx1'/><br>
  204. Domoticz Idx 2: <input type='number' name='domIdx2' id='domIdx2'/><br>
  205. Domoticz Idx 3: <input type='number' name='domIdx3' id='domIdx3'/><br>
  206. <h4>Button MQTT-Out</h4>
  207. Retain *: <input type='checkbox' name='btnRet' id='btnRet'/><br><br>
  208. 1:<br>
  209. Topic: <input type='text' name='top1' id='top1'/> Payload: <input type='text' name='pld1' id='pld1'/><br>
  210. Hold:<br>
  211. Control relais: <select name='hld1ToRel' id='hld1ToRel'><option value='0'>-</option><option>1</option><option>2</option><option>3</option></select><br>
  212. Topic: <input type='text' name='topHld1' id='topHld1'/> Payload: <input type='text' name='pldHld1' id='pldHld1'/><br><br>
  213. 2:<br>
  214. Topic: <input type='text' name='top2' id='top2'/> Payload: <input type='text' name='pld2' id='pld2'/><br>
  215. Hold:<br>
  216. Control relais: <select name='hld2ToRel' id='hld2ToRel'><option value='0'>-</option><option>1</option><option>2</option><option>3</option></select><br>
  217. Topic: <input type='text' name='topHld2' id='topHld2'/> Payload: <input type='text' name='pldHld2' id='pldHld2'/><br><br>
  218. 3:<br>
  219. Topic: <input type='text' name='top3' id='top3'/> Payload: <input type='text' name='pld3' id='pld3'/><br>
  220. Hold:<br>
  221. Control relais: <select name='hld3ToRel' id='hld3ToRel'><option value='0'>-</option><option>1</option><option>2</option><option>3</option></select><br>
  222. Topic: <input type='text' name='topHld3' id='topHld3'/> Payload: <input type='text' name='pldHld3' id='pldHld3'/><br>
  223. <br>
  224. <input type='submit' value='Save'/>
  225. </form>
  226. <form id='rebootForm' onsubmit='return res()'>
  227. <input type='submit' value='Restart'/>
  228. </form>
  229. <script>
  230. function g(i) { return document.getElementById(i) };
  231. var xhttp, reqTime, reqFin, rxhttp;
  232. function res() {
  233. rxhttp = new XMLHttpRequest();
  234. rxhttp.timeout = 1000;
  235. rxhttp.open('POST', 'restart');
  236. rxhttp.send('');
  237. rxhttp = null;
  238. return false;
  239. }
  240. function setCheckbox(ele, dat) {
  241. if(dat == 1) {
  242. ele.checked = true;
  243. ele.style.visibility = 'visible';
  244. }
  245. else {
  246. ele.checked = false;
  247. ele.style.visibility = 'visible';
  248. }
  249. }
  250. function updateCheckboxValue(ele) {
  251. if (ele.checked) ele.value ='1';
  252. else {
  253. ele.value = '0';
  254. ele.checked = true;
  255. ele.style.visibility = 'hidden';
  256. }
  257. }
  258. function transmit(f) {
  259. if (!xhttp) {
  260. updateCheckboxValue(g('btnRet'));
  261. xhttp = new XMLHttpRequest();
  262. xhttp.timeout = 2000;
  263. xhttp.open('POST', 'confdata2');
  264. xhttp.send(f ? (new FormData(f)) : '');
  265. xhttp.onreadystatechange = function () {
  266. if (xhttp.readyState === XMLHttpRequest.DONE && xhttp.status === 200) {
  267. var data = JSON.parse(xhttp.responseText);
  268. setCheckbox(g('btnRet'), data.btnRet);
  269. g('top1').value = data.top1;
  270. g('top2').value = data.top2;
  271. g('top3').value = data.top3;
  272. g('topHld1').value = data.topHld1;
  273. g('topHld2').value = data.topHld2;
  274. g('topHld3').value = data.topHld3;
  275. g('pld1').value = data.pld1;
  276. g('pld2').value = data.pld2;
  277. g('pld3').value = data.pld3;
  278. g('pldHld1').value = data.pldHld1;
  279. g('pldHld2').value = data.pldHld2;
  280. g('pldHld3').value = data.pldHld3;
  281. g('hld1ToRel').value = data.hld1ToRel;
  282. g('hld2ToRel').value = data.hld2ToRel;
  283. g('hld3ToRel').value = data.hld3ToRel;
  284. g('domIdx1').value = data.domIdx1;
  285. g('domIdx2').value = data.domIdx2;
  286. g('domIdx3').value = data.domIdx3;
  287. xhttp = null;
  288. reqFin = false;
  289. }
  290. else {
  291. if(!reqFin && reqTime > 10) {
  292. xhttp = null;
  293. reqFin = true;
  294. }
  295. }
  296. }
  297. }
  298. return false;
  299. }
  300. transmit();
  301. setInterval(function () { ++reqTime; }, 1000);
  302. </script>
  303. </body></html>)"; //httpConf2Page
  304. static const char httpConfHwPage[] PROGMEM =
  305. R"(<html><head><body>
  306. <h3>Hardware configuration</h3>
  307. <a href='/'>Home</a><br><br>
  308. <input type='button' value='reload' onclick='return transmit()'/><br>
  309. <form id='form1' onsubmit='return transmit(this)'>
  310. <br>
  311. Avoid duplicate GPIO assignments!<br>
  312. GPIO 0 and 2 have fixed 10k pullup and must remain high during boot (otherwise flash mode is entered).<br>
  313. GPIO 2 is also connected to builtin LED (active LOW) on most ESP boards, so don't care or strip it.<br>
  314. GPIO 15 has 10k pull-down, so could only be used as active-high in/output.<br>
  315. Some GPIOs go high for some time at boot, so using only active-low logic is advisable, particularly for switching outputs<br>
  316. Invert = active HIGH, default LOW<br>
  317. Impulses are 0 by default (on until off), otherwise will auto-turn-off after specified time in factors of 100ms.<br>
  318. <h4>Relais</h4>
  319. 1 - Enable: <input type='checkbox' name='enaRel1' id='enaRel1'/><br>
  320. GPIO: <select name='ioRel1' id='ioRel1'><option>0</option><option>2</option><option>4</option><option>5</option><option>12</option><option>13</option><option>14</option><option>15</option></select><br>
  321. Impulse: <input type='number' name='puls1' id='puls1'/><br>
  322. invert: <input type='checkbox' name='invRel1' id='invRel1'/><br><br>
  323. 2 - Enable: <input type='checkbox' name='enaRel2' id='enaRel2'/><br>
  324. GPIO: <select name='ioRel2' id='ioRel2'><option>0</option><option>2</option><option>4</option><option>5</option><option>12</option><option>13</option><option>14</option><option>15</option></select><br>
  325. Impulse: <input type='number' name='puls2' id='puls2'/><br>
  326. invert: <input type='checkbox' name='invRel2' id='invRel2'/><br><br>
  327. 3 - Enable: <input type='checkbox' name='enaRel3' id='enaRel3'/><br>
  328. GPIO: <select name='ioRel3' id='ioRel3'><option>0</option><option>2</option><option>4</option><option>5</option><option>12</option><option>13</option><option>14</option><option>15</option></select><br>
  329. Impulse: <input type='number' name='puls3' id='puls3'/><br>
  330. invert: <input type='checkbox' name='invRel3' id='invRel3'/><br>
  331. <h4>Buttons</h4>
  332. Debounce time: <input type='number' name='debtime' id='debtime'/> in ms. default: 120<br>
  333. Hold time: <input type='number' name='hldtime' id='hldtime'/> in ms. default: 750<br><br>
  334. 1 - Enable: <input type='checkbox' name='enaBtn1' id='enaBtn1'/><br>
  335. GPIO: <select name='ioBtn1' id='ioBtn1'><option>0</option><option>2</option><option>4</option><option>5</option><option>12</option><option>13</option><option>14</option><option>15</option></select><br>
  336. invert: <input type='checkbox' name='invBtn1' id='invBtn1'/><br><br>
  337. 2 - Enable: <input type='checkbox' name='enaBtn2' id='enaBtn2'/><br>
  338. GPIO: <select name='ioBtn2' id='ioBtn2'><option>0</option><option>2</option><option>4</option><option>5</option><option>12</option><option>13</option><option>14</option><option>15</option></select><br>
  339. invert: <input type='checkbox' name='invBtn2' id='invBtn2'/><br><br>
  340. 3 - Enable: <input type='checkbox' name='enaBtn3' id='enaBtn3'/><br>
  341. GPIO: <select name='ioBtn3' id='ioBtn3'><option>0</option><option>2</option><option>4</option><option>5</option><option>12</option><option>13</option><option>14</option><option>15</option></select><br>
  342. invert: <input type='checkbox' name='invBtn3' id='invBtn3'/><br>
  343. <h4>Status LEDs</h4>
  344. 1 - Enable: <input type='checkbox' name='enaLed1' id='enaLed1'/><br>
  345. GPIO: <select name='ioLed1' id='ioLed1'><option>0</option><option>2</option><option>4</option><option>5</option><option>12</option><option>13</option><option>14</option><option>15</option></select><br>
  346. invert: <input type='checkbox' name='invLed1' id='invLed1'/><br><br>
  347. 2 - Enable: <input type='checkbox' name='enaLed2' id='enaLed2'/><br>
  348. GPIO: <select name='ioLed2' id='ioLed2'><option>0</option><option>2</option><option>4</option><option>5</option><option>12</option><option>13</option><option>14</option><option>15</option></select><br>
  349. invert: <input type='checkbox' name='invLed2' id='invLed2'/><br><br>
  350. 3 - Enable: <input type='checkbox' name='enaLed3' id='enaLed3'/><br>
  351. GPIO: <select name='ioLed3' id='ioLed3'><option>0</option><option>2</option><option>4</option><option>5</option><option>12</option><option>13</option><option>14</option><option>15</option></select><br>
  352. invert: <input type='checkbox' name='invLed3' id='invLed3'/><br><br>
  353. <br>
  354. <input type='submit' value='Save'/>
  355. </form>
  356. <form id='rebootForm' onsubmit='return res()'>
  357. <input type='submit' value='Restart'/>
  358. </form>
  359. <script>
  360. function g(i) { return document.getElementById(i) };
  361. var xhttp, reqTime, reqFin, rxhttp;
  362. function res() {
  363. rxhttp = new XMLHttpRequest();
  364. rxhttp.timeout = 1000;
  365. rxhttp.open('POST', 'restart');
  366. rxhttp.send('');
  367. rxhttp = null;
  368. return false;
  369. }
  370. function setCb(ele, dat) {
  371. if(dat == 1) {
  372. ele.checked = true;
  373. ele.style.visibility = 'visible';
  374. }
  375. else {
  376. ele.checked = false;
  377. ele.style.visibility = 'visible';
  378. }
  379. }
  380. function updCbVal(ele) {
  381. if (ele.checked) ele.value ='1';
  382. else {
  383. ele.value = '0';
  384. ele.checked = true;
  385. ele.style.visibility = 'hidden';
  386. }
  387. }
  388. function transmit(f) {
  389. if (!xhttp) {
  390. updCbVal(g('enaRel1'));
  391. updCbVal(g('enaRel2'));
  392. updCbVal(g('enaRel3'));
  393. updCbVal(g('enaBtn1'));
  394. updCbVal(g('enaBtn2'));
  395. updCbVal(g('enaBtn3'));
  396. updCbVal(g('invRel1'));
  397. updCbVal(g('invRel2'));
  398. updCbVal(g('invRel3'));
  399. updCbVal(g('invBtn1'));
  400. updCbVal(g('invBtn2'));
  401. updCbVal(g('invBtn3'));
  402. updCbVal(g('enaLed1'));
  403. updCbVal(g('enaLed2'));
  404. updCbVal(g('enaLed3'));
  405. updCbVal(g('invLed1'));
  406. updCbVal(g('invLed2'));
  407. updCbVal(g('invLed3'));
  408. xhttp = new XMLHttpRequest();
  409. xhttp.timeout = 2000;
  410. xhttp.open('POST', 'confdatahw');
  411. xhttp.send(f ? (new FormData(f)) : '');
  412. xhttp.onreadystatechange = function () {
  413. if (xhttp.readyState === XMLHttpRequest.DONE && xhttp.status === 200) {
  414. var data = JSON.parse(xhttp.responseText);
  415. g('debtime').value = data.debtime;
  416. g('hldtime').value = data.hldtime;
  417. g('ioRel1').value = data.ioRel1;
  418. g('ioRel2').value = data.ioRel2;
  419. g('ioRel3').value = data.ioRel3;
  420. g('puls1').value = data.puls1;
  421. g('puls2').value = data.puls2;
  422. g('puls3').value = data.puls3;
  423. g('ioBtn1').value = data.ioBtn1;
  424. g('ioBtn2').value = data.ioBtn2;
  425. g('ioBtn3').value = data.ioBtn3;
  426. g('ioLed1').value = data.ioLed1;
  427. g('ioLed2').value = data.ioLed2;
  428. g('ioLed3').value = data.ioLed3;
  429. setCb(g('enaRel1'), data.enaRel1);
  430. setCb(g('enaRel2'), data.enaRel2);
  431. setCb(g('enaRel3'), data.enaRel3);
  432. setCb(g('enaBtn1'), data.enaBtn1);
  433. setCb(g('enaBtn2'), data.enaBtn2);
  434. setCb(g('enaBtn3'), data.enaBtn3);
  435. setCb(g('invRel1'), data.invRel1);
  436. setCb(g('invRel2'), data.invRel2);
  437. setCb(g('invRel3'), data.invRel3);
  438. setCb(g('invBtn1'), data.invBtn1);
  439. setCb(g('invBtn2'), data.invBtn2);
  440. setCb(g('invBtn3'), data.invBtn3);
  441. setCb(g('enaLed1'), data.enaLed1);
  442. setCb(g('enaLed2'), data.enaLed2);
  443. setCb(g('enaLed3'), data.enaLed3);
  444. setCb(g('invLed1'), data.invLed1);
  445. setCb(g('invLed2'), data.invLed2);
  446. setCb(g('invLed3'), data.invLed3);
  447. xhttp = null;
  448. reqFin = false;
  449. }
  450. else {
  451. if(!reqFin && reqTime > 10) {
  452. xhttp = null;
  453. reqFin = true;
  454. }
  455. }
  456. }
  457. }
  458. return false;
  459. }
  460. transmit();
  461. setInterval(function () { ++reqTime; }, 1000);
  462. </script>
  463. </body></html>)"; //httpConfHwPage
  464. void httpServerHandleRoot() {
  465. boolean sendData = false;
  466. if (strlen(http_user) > 0 && strlen(http_pass) > 0) {
  467. if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication();
  468. sendData = true;
  469. }
  470. else sendData = true;
  471. if (sendData) {
  472. httpServer.send_P(200, "text/html", httpRoot);
  473. }
  474. }
  475. void httpServerHandleConfPage() {
  476. boolean sendData = false;
  477. if (strlen(http_user) > 0 && strlen(http_pass) > 0) {
  478. if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication();
  479. sendData = true;
  480. }
  481. else sendData = true;
  482. if (sendData) {
  483. httpServer.send_P(200, "text/html", httpConfPage);
  484. }
  485. }
  486. void httpServerHandleConf2Page() {
  487. boolean sendData = false;
  488. if (strlen(http_user) > 0 && strlen(http_pass) > 0) {
  489. if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication();
  490. sendData = true;
  491. }
  492. else sendData = true;
  493. if (sendData) {
  494. httpServer.send_P(200, "text/html", httpConf2Page);
  495. }
  496. }
  497. void httpServerHandleConfHwPage() {
  498. boolean sendData = false;
  499. if (strlen(http_user) > 0 && strlen(http_pass) > 0) {
  500. if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication();
  501. sendData = true;
  502. }
  503. else sendData = true;
  504. if (sendData) {
  505. httpServer.send_P(200, "text/html", httpConfHwPage);
  506. }
  507. }
  508. //void httpServerHandleNotFound() {
  509. // String message = "File Not Found\n\n";
  510. // message += "URI: ";
  511. // message += httpServer.uri();
  512. // message += "\nMethod: ";
  513. // message += (httpServer.method() == HTTP_GET) ? "GET" : "POST";
  514. // message += "\nArguments: ";
  515. // message += httpServer.args();
  516. // message += "\n";
  517. // for (uint8_t i = 0; i < httpServer.args(); i++) {
  518. // message += " " + httpServer.argName(i) + ": " + httpServer.arg(i) + "\n";
  519. // }
  520. // httpServer.send(404, "text/plain", message);
  521. //}
  522. void httpServerHandleNotFound() {
  523. // if (strlen(http_user) > 0 && strlen(http_pass) > 0) {
  524. // if (!httpServer.authenticate(http_user, http_pass))
  525. // return httpServer.requestAuthentication();
  526. httpServer.send(404, "text/plain", "");
  527. //}
  528. }
  529. void httpServerInit() {
  530. httpServer.on("/delconf", []() {
  531. Serial.println("httpServer.on /delconf");
  532. if (httpServer.hasArg("token")) {
  533. char buf[20];
  534. httpServer.arg("token").toCharArray(buf, 20);
  535. if (strcmp(buf, CLEARCONF_TOKEN) == 0) {
  536. // httpServer.send(200, "text/plain", "Token OK - deleting config");
  537. deleteConfig();
  538. }
  539. } //if
  540. // else {
  541. // httpServer.send(200, "text/plain", "not allowed");
  542. // }
  543. });
  544. httpServer.on("/api", []() {
  545. boolean sendData = false;
  546. if (strlen(http_user) > 0 && strlen(http_pass) > 0) {
  547. if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication();
  548. sendData = true;
  549. }
  550. else sendData = true;
  551. if (sendData) {
  552. //Serial.println("httpServer.on /api");
  553. if (httpServer.hasArg("Btn1")) {
  554. lastSwitchSource[0] = 2;
  555. relaisToggle(0);
  556. Serial.println("web Btn1");
  557. } //if
  558. if (httpServer.hasArg("Btn2")) {
  559. lastSwitchSource[1] = 2;
  560. relaisToggle(1);
  561. Serial.println("web Btn2");
  562. } //if
  563. yield();
  564. if (httpServer.hasArg("Btn3")) {
  565. lastSwitchSource[2] = 2;
  566. relaisToggle(2);
  567. Serial.println("web Btn3");
  568. } //if
  569. if (httpServer.hasArg("allOn")) {
  570. lastSwitchSource[0] = 2;
  571. lastSwitchSource[1] = 2;
  572. lastSwitchSource[2] = 2;
  573. allRelaisOn();
  574. Serial.println("web allOn");
  575. } //if
  576. if (httpServer.hasArg("allOff")) {
  577. lastSwitchSource[0] = 2;
  578. lastSwitchSource[1] = 2;
  579. lastSwitchSource[2] = 2;
  580. allRelaisOff();
  581. Serial.println("web allOff");
  582. } //if
  583. yield();
  584. //build json object of program data
  585. StaticJsonBuffer<200> jsonBuffer;
  586. JsonObject &json = jsonBuffer.createObject();
  587. json["ssid"] = WiFi.SSID();
  588. if (relais_enabled[0]) json["swState1"] = relais_state[0];
  589. if (relais_enabled[1]) json["swState2"] = relais_state[1];
  590. if (relais_enabled[2]) json["swState3"] = relais_state[2];
  591. json["devname"] = deviceName;
  592. yield();
  593. char jsonchar[200];
  594. json.printTo(jsonchar); //print to char array, takes more memory but sends in one piece
  595. httpServer.send(200, "application/json", jsonchar);
  596. }
  597. }); //httpServer.on /api
  598. httpServer.on("/restart", []() {
  599. Serial.println("web triggered restart");
  600. ESP.restart();
  601. });
  602. httpServer.on("/confdata", []() {
  603. boolean sendData = false;
  604. if (strlen(http_user) > 0 && strlen(http_pass) > 0) {
  605. if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication();
  606. sendData = true;
  607. }
  608. else sendData = true;
  609. if (sendData) {
  610. Serial.println("httpServer.on /confdata");
  611. for (int i = 0; i < httpServer.args(); i++) {
  612. char bufName[20];
  613. char bufValue[101];
  614. httpServer.argName(i).toCharArray(bufName, 20);
  615. httpServer.arg(i).toCharArray(bufValue, 101);
  616. if (strlen(bufName) > 0) {
  617. Serial.print("web update ");
  618. Serial.print(bufName);
  619. Serial.print(" = ");
  620. Serial.println(bufValue);
  621. setConfig(bufName, bufValue);
  622. }
  623. saveConfigToFlash = true; // will be saved in next loop()
  624. Serial.println("web triggered saveConfigToFlash");
  625. }
  626. yield();
  627. //build json object of program data
  628. StaticJsonBuffer<1000> jsonBuffer;
  629. JsonObject &json = jsonBuffer.createObject();
  630. json["devName"] = deviceName;
  631. json["httpUser"] = http_user;
  632. json["httpPass"] = http_pass;
  633. json["mqttHost"] = mqtt_server;
  634. json["mqttPort"] = mqtt_port;
  635. json["mqttUser"] = mqtt_user;
  636. json["mqttPass"] = mqtt_pass;
  637. json["inTop"] = mqtt_topic_in;
  638. json["outTop"] = mqtt_topic_out;
  639. json["outRet"] = mqtt_outRetain;
  640. json["willTop"] = mqtt_willTopic;
  641. json["willQos"] = mqtt_willQos;
  642. json["willRet"] = mqtt_willRetain;
  643. json["willMsg"] = mqtt_willMsg;
  644. json["domOutTop"] = domoticz_out_topic;
  645. json["allOnOffTop"] = mqtt_allOnOffTopic;
  646. yield();
  647. char jsonchar[1000];
  648. json.printTo(jsonchar); //print to char array, takes more memory but sends in one piece
  649. httpServer.send(200, "application/json", jsonchar);
  650. }
  651. }); //httpServer.on /confdata
  652. httpServer.on("/confdata2", []() {
  653. boolean sendData = false;
  654. if (strlen(http_user) > 0 && strlen(http_pass) > 0) {
  655. if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication();
  656. sendData = true;
  657. }
  658. else sendData = true;
  659. if (sendData) {
  660. Serial.println("httpServer.on /confdata2");
  661. for (int i = 0; i < httpServer.args(); i++) {
  662. char bufName[20];
  663. char bufValue[101];
  664. httpServer.argName(i).toCharArray(bufName, 20);
  665. httpServer.arg(i).toCharArray(bufValue, 101);
  666. if (strlen(bufName) > 0) {
  667. Serial.print("web update ");
  668. Serial.print(bufName);
  669. Serial.print(" = ");
  670. Serial.println(bufValue);
  671. setConfig(bufName, bufValue);
  672. }
  673. saveConfig2ToFlash = true;
  674. Serial.println("web triggered saveConfig2ToFlash");
  675. }
  676. yield();
  677. //build json object of program data
  678. StaticJsonBuffer<1000> jsonBuffer;
  679. JsonObject &json = jsonBuffer.createObject();
  680. json["btnRet"] = mqtt_btnRetain;
  681. json["top1"] = mqtt_topic_out_1;
  682. json["top2"] = mqtt_topic_out_2;
  683. json["top3"] = mqtt_topic_out_3;
  684. json["pld1"] = mqtt_payload_out_1;
  685. json["pld2"] = mqtt_payload_out_2;
  686. json["pld3"] = mqtt_payload_out_3;
  687. json["topHld1"] = mqtt_topic_out_hold_1;
  688. json["topHld2"] = mqtt_topic_out_hold_2;
  689. json["topHld3"] = mqtt_topic_out_hold_3;
  690. json["pldHld1"] = mqtt_payload_out_hold_1;
  691. json["pldHld2"] = mqtt_payload_out_hold_2;
  692. json["pldHld3"] = mqtt_payload_out_hold_3;
  693. json["domIdx1"] = domoticzIdx[0];
  694. json["domIdx2"] = domoticzIdx[1];
  695. json["domIdx3"] = domoticzIdx[2];
  696. json["hld1ToRel"] = hldToRel[0];
  697. json["hld2ToRel"] = hldToRel[1];
  698. json["hld3ToRel"] = hldToRel[2];
  699. yield();
  700. char jsonchar[1000];
  701. json.printTo(jsonchar); //print to char array, takes more memory but sends in one piece
  702. httpServer.send(200, "application/json", jsonchar);
  703. }
  704. }); //httpServer.on /confdata2
  705. httpServer.on("/confdatahw", []() {
  706. boolean sendData = false;
  707. if (strlen(http_user) > 0 && strlen(http_pass) > 0) {
  708. if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication();
  709. sendData = true;
  710. }
  711. else sendData = true;
  712. if (sendData) {
  713. Serial.println("httpServer.on /confdatahw");
  714. for (int i = 0; i < httpServer.args(); i++) {
  715. char bufName[20];
  716. char bufValue[101];
  717. httpServer.argName(i).toCharArray(bufName, 20);
  718. httpServer.arg(i).toCharArray(bufValue, 101);
  719. if (strlen(bufName) > 0) {
  720. Serial.print("web update ");
  721. Serial.print(bufName);
  722. Serial.print(" = ");
  723. Serial.println(bufValue);
  724. setConfig(bufName, bufValue);
  725. }
  726. saveConfigHwToFlash = true;
  727. Serial.println("web triggered saveConfigHwToFlash");
  728. }
  729. yield();
  730. //build json object of program data
  731. StaticJsonBuffer<1000> jsonBuffer;
  732. JsonObject &json = jsonBuffer.createObject();
  733. json["debtime"] = debounceTime;
  734. json["hldtime"] = buttonHoldTime;
  735. json["enaRel1"] = relais_enabled[0];
  736. json["enaRel2"] = relais_enabled[1];
  737. json["enaRel3"] = relais_enabled[2];
  738. json["enaBtn1"] = button_enabled[0];
  739. json["enaBtn2"] = button_enabled[1];
  740. json["enaBtn3"] = button_enabled[2];
  741. json["enaLed1"] = led_enabled[0];
  742. json["enaLed2"] = led_enabled[1];
  743. json["enaLed3"] = led_enabled[2];
  744. json["ioRel1"] = relais_pins[0];
  745. json["ioRel2"] = relais_pins[1];
  746. json["ioRel3"] = relais_pins[2];
  747. json["ioBtn1"] = buttons_pins[0];
  748. json["ioBtn2"] = buttons_pins[1];
  749. json["ioBtn3"] = buttons_pins[2];
  750. json["ioLed1"] = leds_pins[0];
  751. json["ioLed2"] = leds_pins[1];
  752. json["ioLed3"] = leds_pins[2];
  753. json["invRel1"] = relais_invert[0];
  754. json["invRel2"] = relais_invert[1];
  755. json["invRel3"] = relais_invert[2];
  756. json["invBtn1"] = button_invert[0];
  757. json["invBtn2"] = button_invert[1];
  758. json["invBtn3"] = button_invert[2];
  759. json["invLed1"] = led_invert[0];
  760. json["invLed2"] = led_invert[1];
  761. json["invLed3"] = led_invert[2];
  762. json["puls1"] = relais_impulse[0];
  763. json["puls2"] = relais_impulse[1];
  764. json["puls3"] = relais_impulse[2];
  765. yield();
  766. char jsonchar[1000];
  767. json.printTo(jsonchar); //print to char array, takes more memory but sends in one piece
  768. httpServer.send(200, "application/json", jsonchar);
  769. }
  770. }); //httpServer.on /confdatahw
  771. //get heap status, analog input value and all GPIO statuses in one json call
  772. httpServer.on("/info", HTTP_GET, []() {
  773. boolean sendData = false;
  774. if (strlen(http_user) > 0 && strlen(http_pass) > 0) {
  775. if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication();
  776. sendData = true;
  777. }
  778. else sendData = true;
  779. if (sendData) {
  780. String json = "{";
  781. json += "\"wifissid\":\"" + WiFi.SSID() + "\"";
  782. json += "\"heap\":" + String(ESP.getFreeHeap());
  783. json += "}";
  784. httpServer.send(200, "text/json", json);
  785. json = String();
  786. }
  787. }); //httpServer.on /info
  788. httpServer.on("/", []() {
  789. httpServerHandleRoot();
  790. });
  791. httpServer.on("/conf", []() {
  792. httpServerHandleConfPage();
  793. });
  794. httpServer.on("/conf2", []() {
  795. httpServerHandleConf2Page();
  796. });
  797. httpServer.on("/confhw", []() {
  798. httpServerHandleConfHwPage();
  799. });
  800. httpServer.onNotFound([]() {
  801. httpServerHandleNotFound();
  802. }); //httpServer.onNotFound
  803. // HTTP Updater at /update
  804. httpUpdater.setup(&httpServer);
  805. httpServer.begin();
  806. }