httpServer.ino 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  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. <div style='font-size:xx-large'>
  10. <div id='sw1div'>1: <input type='button' id='tbtn1' onclick='return sendBtn(1)'/><br></div>
  11. <div id='sw2div' style='display:none;'>2: <input type='button' id='tbtn2' onclick='return sendBtn(2)'/><br></div>
  12. <div id='sw3div' style='display:none'>3: <input type='button' id='tbtn3' onclick='return sendBtn(3)'/><br></div>
  13. </div>
  14. <br>
  15. <br>
  16. WiFi verbunden mit <i><span id='ssid'></span></i>.<br>
  17. <h6>Letztes Update vor
  18. <span id='ut'></span> Sekunden.
  19. <span id='status'></span>
  20. </h6>
  21. <br>
  22. <a href='/wifi.htm'>WiFi-Einstellungen</a><br>
  23. <a href='/conf'>Basis-Einstellungen</a><br>
  24. <a href='/conf2'>Erweiterte Einstellungen</a><br>
  25. <a href='/update'>Firmware Update</a>
  26. <script>
  27. function g(i) { return document.getElementById(i) };
  28. var xhttp, updateTime, reqTime, reqFin;
  29. var textA = 'AUS';
  30. var textE = 'EIN';
  31. function sendBtn(btn) {
  32. var frmn='BtnFrm'+btn;
  33. var form = g(frmn);
  34. return transmit(form);
  35. }
  36. function transmit(f) {
  37. if (!xhttp) {
  38. g('status').innerHTML = 'l&auml;dt...';
  39. reqTime = 0;
  40. reqFin = false;
  41. xhttp = new XMLHttpRequest();
  42. xhttp.timeout = 2000;
  43. xhttp.open('POST', 'api');
  44. xhttp.send(f ? (new FormData(f)) : '');
  45. xhttp.onreadystatechange = function () {
  46. if (xhttp.readyState === XMLHttpRequest.DONE && xhttp.status === 200) {
  47. var data = JSON.parse(xhttp.responseText);
  48. g('ssid').innerHTML = data.ssid;
  49. if(data.devname != undefined) g('devname').innerHTML = data.devname;
  50. if(data.swState2 != undefined) g('sw2div').style.display='inline';
  51. else g('sw2div').style.display='none';
  52. if(data.swState3 != undefined) g('sw3div').style.display='inline';
  53. else g('sw3div').style.display='none';
  54. if(data.swState1 == '1') g('tbtn1').value = textE;
  55. else g('tbtn1').value = textA;
  56. if(data.swState2 == '1') g('tbtn2').value = textE;
  57. else g('tbtn2').value = textA;
  58. if(data.swState3 == '1') g('tbtn3').value = textE;
  59. else g('tbtn3').value = textA;
  60. xhttp = null;
  61. updateTime = 0;
  62. reqFin = true;
  63. }
  64. else{
  65. if(!reqFin && reqTime > 10) {
  66. xhttp = null;
  67. reqFin = true;
  68. }
  69. }
  70. }
  71. }
  72. return false;
  73. }
  74. transmit();
  75. setInterval(function () { g('ut').innerHTML = ++updateTime; ++reqTime; }, 1000);
  76. setInterval(transmit, 5000);
  77. </script>
  78. </body></html>)";
  79. static const char httpConfPage[] PROGMEM =
  80. R"(<html><head><body>
  81. <h3>Configuration</h3>
  82. <a href='/'>Home</a><br>
  83. <input type='button' value='reload' onclick='return transmit()'/><br><br>
  84. <form id='form1' onsubmit='return transmit(this)'>
  85. Device Name: <input type='text' name='devName' id='devName'/><br>
  86. HTTP User *: <input type='text' name='httpUser' id='httpUser'/><br>
  87. HTTP Password *: <input type='password' name='httpPass' id='httpPass'/><br>
  88. MQTT Server *: <input type='text' name='mqttHost' id='mqttHost'/><br>
  89. MQTT Port *: <input type='number' name='mqttPort' id='mqttPort'/><br>
  90. MQTT User *: <input type='text' name='mqttUser' id='mqttUser'/><br>
  91. MQTT Password *: <input type='password' name='mqttPass' id='mqttPass'/><br>
  92. In Topic *: <input type='text' name='inTop' id='inTop'/><br>
  93. Out Topic: <input type='text' name='outTop' id='outTop'/><br>
  94. LastWill Topic *: <input type='text' name='willTop' id='willTop'/><br>
  95. LastWill Qos *: <input type='number' name='willQos' id='willQos'/><br>
  96. LastWill Retain *: <input type='checkbox' name='willRet' id='willRet'/><br>
  97. LastWill Message *: <input type='text' name='willMsg' id='willMsg'/><br>
  98. Domoticz Out Topic *: <input type='text' name='domoOutTop' id='domoOutTop'/><br>
  99. <br>
  100. <input type='submit' value='Save'/>
  101. </form>
  102. <form id='restartForm' onsubmit='return res()'>
  103. <input type='hidden' name='restart' value='1'>
  104. <input type='submit' value='Restart'/>
  105. </form>
  106. <script>
  107. function g(i) { return document.getElementById(i) };
  108. var xhttp, reqTime, reqFin, rxhttp;
  109. function res() {
  110. rxhttp = new XMLHttpRequest();
  111. rxhttp.timeout = 1000;
  112. rxhttp.open('POST', 'restart');
  113. rxhttp.send('');
  114. rxhttp = null;
  115. return false;
  116. }
  117. function transmit(f) {
  118. if (!xhttp) {
  119. reqTime = 0;
  120. reqFin = false;
  121. var wRet = g('willRet');
  122. if (wRet.checked) wRet.value ='1';
  123. else {
  124. wRet.value = '0';
  125. wRet.checked = true;
  126. wRet.style.visibility = 'hidden';
  127. }
  128. xhttp = new XMLHttpRequest();
  129. xhttp.timeout = 2000;
  130. xhttp.open('POST', 'confdata');
  131. xhttp.send(f ? (new FormData(f)) : '');
  132. xhttp.onreadystatechange = function () {
  133. if (xhttp.readyState === XMLHttpRequest.DONE && xhttp.status === 200) {
  134. var data = JSON.parse(xhttp.responseText);
  135. g('httpUser').value = data.httpUser;
  136. g('httpPass').value = data.httpPass;
  137. g('devName').value = data.devName
  138. g('mqttHost').value = data.mqttHost;
  139. g('mqttPort').value = data.mqttPort;
  140. g('mqttUser').value = data.mqttUser;
  141. g('mqttPass').value = data.mqttPass;
  142. g('inTop').value = data.inTop;
  143. g('outTop').value = data.outTop;
  144. g('willTop').value = data.willTop;
  145. g('willQos').value = data.willQos;
  146. if(data.willRet == 1) {
  147. wRet.checked = true;
  148. wRet.style.visibility = 'visible';
  149. }
  150. else {
  151. wRet.checked = false;
  152. wRet.style.visibility = 'visible';
  153. }
  154. g('willMsg').value = data.willMsg;
  155. g('domoOutTop').value = data.domoOutTop;
  156. xhttp = null;
  157. reqFin = true;
  158. }
  159. else{
  160. if(!reqFin && reqTime > 10) {
  161. xhttp = null;
  162. reqFin = true;
  163. }
  164. }
  165. }
  166. }
  167. return false;
  168. }
  169. transmit();
  170. setInterval(function () { ++reqTime; }, 1000);
  171. </script>
  172. </body></html>)";
  173. static const char httpConf2Page[] PROGMEM =
  174. R"(<html><head><body>
  175. <h3>Configuration 2</h3>
  176. <a href='/'>Home</a><br>
  177. <input type='button' value='reload' onclick='return transmit()'/><br><br>
  178. <form id='form1' onsubmit='return transmit(this)'>
  179. used Relais: <input type='number' name='usedRelais' id='usedRelais'/><br>
  180. used Buttons: <input type='number' name='usedButtons' id='usedButtons'/><br>
  181. Out Topic Hold 1: <input type='text' name='outTop_hold1' id='outTop_hold1'/><br>
  182. Out Topic Hold 2: <input type='text' name='outTop_hold2' id='outTop_hold2'/><br>
  183. Out Topic Hold 3: <input type='text' name='outTop_hold3' id='outTop_hold3'/><br>
  184. Out Payload Hold 1: <input type='text' name='outPld_hold1' id='outPld_hold1'/><br>
  185. Out Payload Hold 2: <input type='text' name='outPld_hold2' id='outPld_hold2'/><br>
  186. Out Payload Hold 3: <input type='text' name='outPld_hold3' id='outPld_hold3'/><br>
  187. Domoticz Idx 1: <input type='number' name='domoIdx1' id='domoIdx1'/><br>
  188. Domoticz Idx 2: <input type='number' name='domoIdx2' id='domoIdx2'/><br>
  189. Domoticz Idx 3: <input type='number' name='domoIdx3' id='domoIdx3'/><br>
  190. Relais Impulse 1: <input type='number' name='impuls1' id='impuls1'/><br>
  191. Relais Impulse 2: <input type='number' name='impuls2' id='impuls2'/><br>
  192. Relais Impulse 3: <input type='number' name='impuls3' id='impuls3'/><br>
  193. <br>
  194. <input type='submit' value='Save'/>
  195. </form>
  196. <form id='rebootForm' onsubmit='return res()'>
  197. <input type='submit' value='Restart'/>
  198. </form>
  199. <script>
  200. function g(i) { return document.getElementById(i) };
  201. var xhttp, reqTime, reqFin, rxhttp;
  202. function res() {
  203. rxhttp = new XMLHttpRequest();
  204. rxhttp.timeout = 1000;
  205. rxhttp.open('POST', 'restart');
  206. rxhttp.send('');
  207. rxhttp = null;
  208. return false;
  209. }
  210. function transmit(f) {
  211. if (!xhttp) {
  212. xhttp = new XMLHttpRequest();
  213. xhttp.timeout = 2000;
  214. xhttp.open('POST', 'confdata2');
  215. xhttp.send(f ? (new FormData(f)) : '');
  216. xhttp.onreadystatechange = function () {
  217. if (xhttp.readyState === XMLHttpRequest.DONE && xhttp.status === 200) {
  218. var data = JSON.parse(xhttp.responseText);
  219. g('usedRelais').value = data.usedRelais;
  220. g('usedButtons').value = data.usedButtons;
  221. g('outTop_hold1').value = data.outTop_hold1;
  222. g('outTop_hold2').value = data.outTop_hold2;
  223. g('outTop_hold3').value = data.outTop_hold3;
  224. g('outPld_hold1').value = data.outPld_hold1;
  225. g('outPld_hold2').value = data.outPld_hold2;
  226. g('outPld_hold3').value = data.outPld_hold3;
  227. g('domoIdx1').value = data.domoIdx1;
  228. g('domoIdx2').value = data.domoIdx2;
  229. g('domoIdx3').value = data.domoIdx3;
  230. g('impuls1').value = data.impuls1;
  231. g('impuls2').value = data.impuls2;
  232. g('impuls3').value = data.impuls3;
  233. xhttp = null;
  234. reqFin = false;
  235. }
  236. else {
  237. if(!reqFin && reqTime > 10) {
  238. xhttp = null;
  239. reqFin = true;
  240. }
  241. }
  242. }
  243. }
  244. return false;
  245. }
  246. transmit();
  247. setInterval(function () { ++reqTime; }, 1000);
  248. </script>
  249. </body></html>)";
  250. void httpServerHandleRoot() {
  251. httpServer.send_P(200, "text/html", httpRoot);
  252. }
  253. void httpServerHandleConfPage() {
  254. httpServer.send_P(200, "text/html", httpConfPage);
  255. }
  256. void httpServerHandleConf2Page() {
  257. httpServer.send_P(200, "text/html", httpConf2Page);
  258. }
  259. void httpServerHandleNotFound() {
  260. String message = "File Not Found\n\n";
  261. message += "URI: ";
  262. message += httpServer.uri();
  263. message += "\nMethod: ";
  264. message += (httpServer.method() == HTTP_GET) ? "GET" : "POST";
  265. message += "\nArguments: ";
  266. message += httpServer.args();
  267. message += "\n";
  268. for (uint8_t i = 0; i < httpServer.args(); i++) {
  269. message += " " + httpServer.argName(i) + ": " + httpServer.arg(i) + "\n";
  270. }
  271. httpServer.send(404, "text/plain", message);
  272. }
  273. void httpServerInit() {
  274. httpServer.on("/api", []() {
  275. //Serial.println("httpServer.on /api");
  276. if (httpServer.hasArg("Btn1")) {
  277. lastSwitchSource[0] = 2;
  278. relaisToggle(0);
  279. Serial.println("web Btn1");
  280. } //if
  281. if (httpServer.hasArg("Btn2")) {
  282. lastSwitchSource[1] = 2;
  283. relaisToggle(1);
  284. Serial.println("web Btn2");
  285. } //if
  286. if (httpServer.hasArg("Btn3")) {
  287. lastSwitchSource[2] = 2;
  288. relaisToggle(2);
  289. Serial.println("web Btn3");
  290. } //if
  291. //build json object of program data
  292. StaticJsonBuffer<200> jsonBuffer;
  293. JsonObject &json = jsonBuffer.createObject();
  294. json["ssid"] = WiFi.SSID();
  295. json["swState1"] = relais_state[0];
  296. if (usedRelaisCount > 1) json["swState2"] = relais_state[1];
  297. if (usedRelaisCount > 2) json["swState3"] = relais_state[2];
  298. json["devname"] = deviceName;
  299. char jsonchar[200];
  300. json.printTo(jsonchar); //print to char array, takes more memory but sends in one piece
  301. httpServer.send(200, "application/json", jsonchar);
  302. }); //httpServer.on /api
  303. httpServer.on("/restart", []() {
  304. Serial.println("web triggered restart");
  305. ESP.restart();
  306. });
  307. httpServer.on("/confdata", []() {
  308. Serial.println("httpServer.on /confdata");
  309. // if (httpServer.hasArg("saveToFlash")) {
  310. // if (httpServer.arg("saveToFlash").toInt() == 1) {
  311. // Serial.println("web saveToFlash triggered");
  312. // //saveConfig();
  313. // saveConfigToFlash = true;
  314. // }
  315. // }
  316. // else if (httpServer.hasArg("restart")) {
  317. // if (httpServer.arg("restart").toInt() == 1) {
  318. // Serial.println("web restart triggered");
  319. // ESP.restart();
  320. // }
  321. // }
  322. // else {
  323. for (int i = 0; i < httpServer.args(); i++) {
  324. char bufName[20];
  325. char bufValue[101];
  326. httpServer.argName(i).toCharArray(bufName, 20);
  327. httpServer.arg(i).toCharArray(bufValue, 101);
  328. //if(strcmp(bufName, "willRet") == 0) {
  329. // willRetSet = true;
  330. // }
  331. //if (strlen(bufName) > 0 && strlen(bufValue) > 0) {
  332. if (strlen(bufName) > 0) {
  333. Serial.print("web update ");
  334. Serial.print(bufName);
  335. Serial.print(" = ");
  336. Serial.println(bufValue);
  337. setConfig(bufName, bufValue);
  338. }
  339. saveConfigToFlash = true; // will be saved in next loop()
  340. Serial.println("web triggered saveConfigToFlash");
  341. }
  342. // }
  343. //build json object of program data
  344. StaticJsonBuffer<1000> jsonBuffer;
  345. JsonObject &json = jsonBuffer.createObject();
  346. json["devName"] = deviceName;
  347. json["httpUser"] = http_user;
  348. json["httpPass"] = http_pass;
  349. json["mqttHost"] = mqtt_server;
  350. json["mqttPort"] = mqtt_port;
  351. json["mqttUser"] = mqtt_user;
  352. json["mqttPass"] = mqtt_pass;
  353. json["inTop"] = mqtt_topic_in;
  354. json["outTop"] = mqtt_topic_out;
  355. json["willTop"] = mqtt_willTopic;
  356. json["willQos"] = mqtt_willQos;
  357. json["willRet"] = mqtt_willRetain;
  358. json["willMsg"] = mqtt_willMsg;
  359. json["domoOutTop"] = domoticz_out_topic;
  360. char jsonchar[1000];
  361. json.printTo(jsonchar); //print to char array, takes more memory but sends in one piece
  362. httpServer.send(200, "application/json", jsonchar);
  363. }); //httpServer.on /confdata
  364. httpServer.on("/confdata2", []() {
  365. Serial.println("httpServer.on /confdata2");
  366. // if (httpServer.hasArg("saveToFlash")) {
  367. // if (httpServer.arg("saveToFlash").toInt() == 1) {
  368. // Serial.println("web saveToFlash triggered");
  369. // //saveConfig();
  370. // saveConfigToFlash = true;
  371. // }
  372. // }
  373. // else if (httpServer.hasArg("restart")) {
  374. // if (httpServer.arg("restart").toInt() == 1) {
  375. // Serial.println("web restart triggered");
  376. // ESP.restart();
  377. // }
  378. // }
  379. // else {
  380. for (int i = 0; i < httpServer.args(); i++) {
  381. char bufName[20];
  382. char bufValue[101];
  383. httpServer.argName(i).toCharArray(bufName, 20);
  384. httpServer.arg(i).toCharArray(bufValue, 101);
  385. //if(strcmp(bufName, "willRet") == 0) {
  386. // willRetSet = true;
  387. // }
  388. //if (strlen(bufName) > 0 && strlen(bufValue) > 0) {
  389. if (strlen(bufName) > 0) {
  390. Serial.print("web update ");
  391. Serial.print(bufName);
  392. Serial.print(" = ");
  393. Serial.println(bufValue);
  394. setConfig(bufName, bufValue);
  395. }
  396. saveConfig2ToFlash = true;
  397. Serial.println("web triggered saveConfig2ToFlash");
  398. }
  399. // }
  400. //build json object of program data
  401. StaticJsonBuffer<1000> jsonBuffer;
  402. JsonObject &json = jsonBuffer.createObject();
  403. json["usedRelais"] = usedRelaisCount;
  404. json["usedButtons"] = usedButtonsCount;
  405. json["outTop_hold1"] = mqtt_topic_out_hold_1;
  406. json["outTop_hold2"] = mqtt_topic_out_hold_2;
  407. json["outTop_hold3"] = mqtt_topic_out_hold_3;
  408. json["outPld_hold1"] = mqtt_payload_out_hold_1;
  409. json["outPld_hold2"] = mqtt_payload_out_hold_2;
  410. json["outPld_hold3"] = mqtt_payload_out_hold_3;
  411. json["domoIdx1"] = domoticzIdx[0];
  412. json["domoIdx2"] = domoticzIdx[1];
  413. json["domoIdx3"] = domoticzIdx[2];
  414. json["impuls1"] = relais_impulse[0];
  415. json["impuls2"] = relais_impulse[1];
  416. json["impuls3"] = relais_impulse[2];
  417. char jsonchar[1000];
  418. json.printTo(jsonchar); //print to char array, takes more memory but sends in one piece
  419. httpServer.send(200, "application/json", jsonchar);
  420. }); //httpServer.on /confdata2
  421. //get heap status, analog input value and all GPIO statuses in one json call
  422. httpServer.on("/info", HTTP_GET, []() {
  423. String json = "{";
  424. json += "\"wifissid\":\"" + WiFi.SSID() + "\"";
  425. json += "\"heap\":" + String(ESP.getFreeHeap());
  426. //json += ", \"analog\":" + String(analogRead(A0));
  427. //json += ", \"gpio\":" + String((uint32_t)(((GPI | GPO) & 0xFFFF) | ((GP16I & 0x01) << 16)));
  428. json += "}";
  429. httpServer.send(200, "text/json", json);
  430. json = String();
  431. }); //httpServer.on /info
  432. httpServer.on("/", []() {
  433. httpServerHandleRoot();
  434. });
  435. httpServer.on("/conf", []() {
  436. httpServerHandleConfPage();
  437. });
  438. httpServer.on("/conf2", []() {
  439. httpServerHandleConf2Page();
  440. });
  441. httpServer.onNotFound([]() {
  442. httpServerHandleNotFound();
  443. }); //httpServer.onNotFound
  444. // HTTP Updater at /update
  445. httpUpdater.setup(&httpServer);
  446. httpServer.begin();
  447. }