httpServer.ino 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683
  1. //extern ESP8266WebServer httpServer;
  2. static const char httpRoot[] PROGMEM =
  3. R"(<html><body>
  4. <h1><span id='devname'></span></h1>
  5. <h3>WiFi Thermostat</h3>
  6. <form id='minusBtnFrm'>
  7. <input type='hidden' name='minusBtn' value='1'>
  8. </form>
  9. <form id='plusBtnFrm'>
  10. <input type='hidden' name='plusBtn' value='1'>
  11. </form>
  12. <form id='modeBtnFrm'>
  13. <input type='hidden' name='modeBtn' value='1'>
  14. </form>
  15. <form id='onoffBtnFrm'>
  16. <input type='hidden' name='onoffBtn' value='1'>
  17. </form>
  18. <span style="font-size:xx-large" id='setTemp'></span> &#8451;<br>
  19. <span id='mode'></span><br>
  20. <input type='button' onclick='return sendMinusBtn()' value='-'/>
  21. <input type='button' onclick='return sendPlusBtn()' value='+'/>
  22. <input type='button' onclick='return sendModeBtn()' value='MODE'/>
  23. <br>
  24. <br>
  25. <input id='btn_onoff' type='button' onclick='return sendOnOffBtn()' value=''/><br>
  26. <br>
  27. Current: <span id='temp'></span> &#8451;&nbsp;&nbsp;&nbsp;<span id='hum'></span> %<br>
  28. Heating <span id='heating'></span><br>
  29. <br>
  30. WiFi connected to <i><span id='ssid'></span></i>.<br>
  31. <h6>Last update
  32. <span id='ut'></span> seconds ago.
  33. <span id='status'></span>
  34. </h6>
  35. <br>
  36. <a href='/wifi.htm'>WiFi settings</a><br>
  37. <a href='/conf'>Base configuration</a><br>
  38. <a href='/conf2'>Extended configuration</a><br>
  39. <a href='/update'>Firmware update</a><br>
  40. <a href='/restart'>Restart</a>
  41. <script>
  42. function g(i) { return document.getElementById(i) };
  43. var xhttp, updateTime, reqTime, reqFin;
  44. var textA = 'OFF';
  45. var textE = 'ON';
  46. function sendMinusBtn() {
  47. var form = document.getElementById('minusBtnFrm');
  48. return transmit(form);
  49. }
  50. function sendPlusBtn() {
  51. var form = document.getElementById('plusBtnFrm');
  52. return transmit(form);
  53. }
  54. function sendModeBtn() {
  55. var form = document.getElementById('modeBtnFrm');
  56. return transmit(form);
  57. }
  58. function sendOnOffBtn() {
  59. var form = document.getElementById('onoffBtnFrm');
  60. return transmit(form);
  61. }
  62. function transmit(f) {
  63. if (!xhttp) {
  64. g('status').innerHTML = 'loading...';
  65. reqTime = 0;
  66. reqFin = false;
  67. xhttp = new XMLHttpRequest();
  68. xhttp.timeout = 2000;
  69. xhttp.open('POST', 'api');
  70. xhttp.send(f ? (new FormData(f)) : '');
  71. xhttp.onreadystatechange = function () {
  72. if (xhttp.readyState === XMLHttpRequest.DONE && xhttp.status === 200) {
  73. var data = JSON.parse(xhttp.responseText);
  74. if(data.devname != undefined) g('devname').innerHTML = data.devname;
  75. g('temp').innerHTML = data.temp.toFixed(1);
  76. g('hum').innerHTML = data.hum;
  77. g('setTemp').innerHTML = data.setTemp.toFixed(1);
  78. g('ssid').innerHTML = data.ssid;
  79. g('mode').innerHTML = data.modeName + ' (' + data.mode + ')';
  80. if(data.mode == '0') {
  81. g('btn_onoff').value = textA;
  82. }
  83. else {
  84. g('btn_onoff').value = textE;
  85. }
  86. if(data.heating == '1') g('heating').innerHTML = 'active';
  87. else if(data.heating == '0') g('heating').innerHTML = 'not active';
  88. xhttp = null;
  89. g('status').innerHTML = '';
  90. updateTime = 0;
  91. reqFin = true;
  92. }
  93. else {
  94. if(!reqFin && reqTime > 10) {
  95. xhttp = null;
  96. reqFin = true;
  97. }
  98. }
  99. }
  100. }
  101. return false;
  102. }
  103. transmit();
  104. setInterval(function () { g('ut').innerHTML = ++updateTime; ++reqTime; }, 1000);
  105. setInterval(transmit, 5000);
  106. </script>
  107. </body></html>)";
  108. static const char httpConfPage[] PROGMEM =
  109. R"(<html><head><body>
  110. <h3>Base configuration</h3>
  111. <a href='/'>Home</a><br><br>
  112. <input type='button' value='reload' onclick='return transmit()'/><br><br>
  113. <form id='form1' onsubmit='return transmit(this)'>
  114. Device Name: <input type='text' name='devName' id='devName'/><br><br>
  115. HTTP User *: <input type='text' name='httpUser' id='httpUser'/><br>
  116. HTTP Password *: <input type='text' name='httpPass' id='httpPass'/><br><br>
  117. HTTP set token: <input type='text' name='httpToken' id='httpToken'/><br>
  118. MQTT Server *: <input type='text' name='mqttHost' id='mqttHost'/><br>
  119. MQTT Port *: <input type='number' name='mqttPort' id='mqttPort'/><br>
  120. MQTT User *: <input type='text' name='mqttUser' id='mqttUser'/><br>
  121. MQTT Password *: <input type='text' name='mqttPass' id='mqttPass'/><br><br>
  122. In Topic *: <input type='text' name='inTop' id='inTop'/><br>
  123. Out Topic: <input type='text' name='outTop' id='outTop'/><br>
  124. Out Retain *: <input type='checkbox' name='outRet' id='outRet'/><br><br>
  125. LastWill Topic *: <input type='text' name='willTop' id='willTop'/><br>
  126. LastWill Qos *: <select name='willQos' id='willQos'><option>0</option><option>1</option><option>2</option></select><br>
  127. LastWill Retain *: <input type='checkbox' name='willRet' id='willRet'/><br>
  128. LastWill Message *: <input type='text' name='willMsg' id='willMsg'/><br><br>
  129. Connect Message *: <input type='text' name='connMsg' id='connMsg'/><br><br>
  130. Domoticz Out Topic *: <input type='text' name='domOutTop' id='domOutTop'/><br>
  131. <br>
  132. <input type='submit' value='Save'/>
  133. </form>
  134. <form id='restartForm' onsubmit='return res()'>
  135. <input type='hidden' name='restart' value='1'>
  136. <input type='submit' value='Restart'/>
  137. </form>
  138. <script>
  139. function g(i) { return document.getElementById(i) };
  140. var xhttp, reqTime, reqFin, rxhttp;
  141. function res() {
  142. rxhttp = new XMLHttpRequest();
  143. rxhttp.timeout = 1000;
  144. rxhttp.open('POST', 'restart');
  145. rxhttp.send('');
  146. rxhttp = null;
  147. return false;
  148. }
  149. function setCheckbox(ele, dat) {
  150. if(dat == 1) {
  151. ele.checked = true;
  152. ele.style.visibility = 'visible';
  153. }
  154. else {
  155. ele.checked = false;
  156. ele.style.visibility = 'visible';
  157. }
  158. }
  159. function updateCheckboxValue(ele) {
  160. if (ele.checked) ele.value ='1';
  161. else {
  162. ele.value = '0';
  163. ele.checked = true;
  164. ele.style.visibility = 'hidden';
  165. }
  166. }
  167. function transmit(f) {
  168. if (!xhttp) {
  169. reqTime = 0;
  170. reqFin = false;
  171. updateCheckboxValue(g('outRet'));
  172. updateCheckboxValue(g('willRet'));
  173. xhttp = new XMLHttpRequest();
  174. xhttp.timeout = 2000;
  175. xhttp.open('POST', 'confdata');
  176. xhttp.send(f ? (new FormData(f)) : '');
  177. xhttp.onreadystatechange = function () {
  178. if (xhttp.readyState === XMLHttpRequest.DONE && xhttp.status === 200) {
  179. var data = JSON.parse(xhttp.responseText);
  180. g('httpUser').value = data.httpUser;
  181. g('httpPass').value = data.httpPass;
  182. g('httpToken').value = data.httpToken;
  183. g('devName').value = data.devName
  184. g('mqttHost').value = data.mqttHost;
  185. g('mqttPort').value = data.mqttPort;
  186. g('mqttUser').value = data.mqttUser;
  187. g('mqttPass').value = data.mqttPass;
  188. g('inTop').value = data.inTop;
  189. g('outTop').value = data.outTop;
  190. g('willTop').value = data.willTop;
  191. g('willQos').value = data.willQos;
  192. setCheckbox(g('outRet'), data.outRet);
  193. setCheckbox(g('willRet'), data.willRet);
  194. g('willMsg').value = data.willMsg;
  195. g('connMsg').value = data.connMsg;
  196. g('domOutTop').value = data.domOutTop;
  197. xhttp = null;
  198. reqFin = true;
  199. }
  200. else {
  201. if(!reqFin && reqTime > 10) {
  202. xhttp = null;
  203. reqFin = true;
  204. }
  205. }
  206. }
  207. }
  208. return false;
  209. }
  210. transmit();
  211. setInterval(function () { ++reqTime; }, 1000);
  212. </script>
  213. </body></html>)";
  214. static const char httpConf2Page[] PROGMEM =
  215. R"(<html><head><body>
  216. <h3>Extended configuration</h3>
  217. <a href='/'>Home</a><br><br>
  218. <input type='button' value='reload' onclick='return transmit()'/><br>
  219. <form id='form1' onsubmit='return transmit(this)'>
  220. <h4>Domoticz</h4>
  221. Idx setTemp: <input type='number' name='domIdxTherm' id='domIdxTherm'/><br>
  222. Idx mode: <input type='number' name='domIdxMode' id='domIdxMode'/><br>
  223. Idx TempHum Sensor: <input type='number' name='domIdxTempHum' id='domIdxTempHum'/><br>
  224. Idx Heating: <input type='number' name='domIdxHeating' id='domIdxHeating'/><br>
  225. Idx PIR: <input type='number' name='domIdxPIR' id='domIdxPIR'/><br>
  226. <h4>Outside Temp/Hum via MQTT</h4>
  227. Temp In-Topic: <input type='text' name='outTempTop' id='outTempTop'/><br>
  228. Hum In-Topic: <input type='text' name='outHumTop' id='outHumTop'/><br>
  229. <h4>Additional MQTT publish topics</h4>
  230. PIR sensor: <input type='text' name='PIRTop' id='PIRTop'/><br>
  231. <h4>Auto-Save</h4>
  232. setTemp: <input type='checkbox' name='autoSaveTemp' id='autoSaveTemp'/><br>
  233. Mode: <input type='checkbox' name='autoSaveMode' id='autoSaveMode'/><br>
  234. <h4>Thermostat / Heating</h4>
  235. Min. Off-Time: <input type='number' name='minOffTime' id='minOffTime'/><br>
  236. Min. Temp: <input type='text' name='tempMin' id='tempMin'/><br>
  237. Max. Temp: <input type='text' name='tempMax' id='tempMax'/><br>
  238. Reduction Mode Temp: <input type='text' name='tempLow' id='tempLow'/><br>
  239. Reduction Mode 2 Temp: <input type='text' name='tempLow2' id='tempLow2'/><br>
  240. set temp decrease value: <input type='text' name='tempDec' id='tempDec'/><br>
  241. Hysteresis: <input type='text' name='hyst' id='hyst'/><br>
  242. Temp Correction.: <input type='text' name='tempCorr' id='tempCorr'/><br>
  243. Hum Correction: <input type='number' name='humCorr' id='humCorr'/><br>
  244. <h4>Intervals / Timeouts</h4>
  245. Measure Interval: <input type='number' name='measInt' id='measInt'/><br>
  246. Display Interval: <input type='number' name='dispInt' id='dispInt'/><br>
  247. Display Timeout: <input type='number' name='dispTout' id='dispTout'/><br>
  248. <h4>Names</h4>
  249. Mode Off: <input type='text' name='modename0' id='modename0'/><br>
  250. Mode Normal: <input type='text' name='modename1' id='modename1'/><br>
  251. Mode Reduction 1: <input type='text' name='modename2' id='modename2'/><br>
  252. Mode Reduction 2: <input type='text' name='modename3' id='modename3'/><br>
  253. <h4>Misc</h4>
  254. PIR enables Display: <input type='checkbox' name='PIRenDisp' id='PIRenDisp'/>
  255. <br><br>
  256. <input type='submit' value='Save'/>
  257. </form>
  258. <form id='rebootForm' onsubmit='return res()'>
  259. <input type='submit' value='Restart'/>
  260. </form>
  261. <script>
  262. function g(i) { return document.getElementById(i) };
  263. var xhttp, reqTime, reqFin, rxhttp;
  264. function res() {
  265. rxhttp = new XMLHttpRequest();
  266. rxhttp.timeout = 1000;
  267. rxhttp.open('POST', 'restart');
  268. rxhttp.send('');
  269. rxhttp = null;
  270. return false;
  271. }
  272. function setCheckbox(ele, dat) {
  273. if(dat == 1) {
  274. ele.checked = true;
  275. ele.style.visibility = 'visible';
  276. }
  277. else {
  278. ele.checked = false;
  279. ele.style.visibility = 'visible';
  280. }
  281. }
  282. function updateCheckboxValue(ele) {
  283. if (ele.checked) ele.value ='1';
  284. else {
  285. ele.value = '0';
  286. ele.checked = true;
  287. ele.style.visibility = 'hidden';
  288. }
  289. }
  290. function transmit(f) {
  291. if (!xhttp) {
  292. updateCheckboxValue(g('autoSaveTemp'));
  293. updateCheckboxValue(g('autoSaveMode'));
  294. updateCheckboxValue(g('PIRenDisp'));
  295. xhttp = new XMLHttpRequest();
  296. xhttp.timeout = 2000;
  297. xhttp.open('POST', 'confdata2');
  298. xhttp.send(f ? (new FormData(f)) : '');
  299. xhttp.onreadystatechange = function () {
  300. if (xhttp.readyState === XMLHttpRequest.DONE && xhttp.status === 200) {
  301. var data = JSON.parse(xhttp.responseText);
  302. setCheckbox(g('autoSaveTemp'), data.autoSaveTemp);
  303. setCheckbox(g('autoSaveMode'), data.autoSaveMode);
  304. setCheckbox(g('PIRenDisp'), data.PIRenDisp);
  305. g('domIdxTherm').value = data.domIdxTherm;
  306. g('domIdxMode').value = data.domIdxMode;
  307. g('domIdxTempHum').value = data.domIdxTempHum;
  308. g('domIdxHeating').value = data.domIdxHeating;
  309. g('domIdxPIR').value = data.domIdxPIR;
  310. g('outTempTop').value = data.outTempTop;
  311. g('outHumTop').value = data.outHumTop;
  312. g('PIRTop').value = data.PIRTop;
  313. g('minOffTime').value = data.minOffTime;
  314. g('tempMin').value = data.tempMin;
  315. g('tempMax').value = data.tempMax;
  316. g('tempLow').value = data.tempLow;
  317. g('tempLow2').value = data.tempLow2;
  318. g('tempDec').value = data.tempDec;
  319. g('hyst').value = data.hyst;
  320. g('tempCorr').value = data.tempCorr;
  321. g('humCorr').value = data.humCorr;
  322. g('measInt').value = data.measInt;
  323. g('dispInt').value = data.dispInt;
  324. g('dispTout').value = data.dispTout;
  325. g('modename0').value = data.modename0;
  326. g('modename1').value = data.modename1;
  327. g('modename2').value = data.modename2;
  328. g('modename3').value = data.modename3;
  329. xhttp = null;
  330. reqFin = false;
  331. }
  332. else {
  333. if(!reqFin && reqTime > 10) {
  334. xhttp = null;
  335. reqFin = true;
  336. }
  337. }
  338. }
  339. }
  340. return false;
  341. }
  342. transmit();
  343. setInterval(function () { ++reqTime; }, 1000);
  344. </script>
  345. </body></html>)";
  346. void httpServerHandleRoot() {
  347. httpServer.send_P(200, "text/html", httpRoot);
  348. }
  349. void httpServerHandleConfPage() {
  350. httpServer.send_P(200, "text/html", httpConfPage);
  351. }
  352. void httpServerHandleConf2Page() {
  353. httpServer.send_P(200, "text/html", httpConf2Page);
  354. }
  355. //void httpServerHandleNotFound() {
  356. // String message = "File Not Found\n\n";
  357. // message += "URI: ";
  358. // message += httpServer.uri();
  359. // message += "\nMethod: ";
  360. // message += (httpServer.method() == HTTP_GET) ? "GET" : "POST";
  361. // message += "\nArguments: ";
  362. // message += httpServer.args();
  363. // message += "\n";
  364. // for (uint8_t i = 0; i < httpServer.args(); i++) {
  365. // message += " " + httpServer.argName(i) + ": " + httpServer.arg(i) + "\n";
  366. // }
  367. // httpServer.send(404, "text / plain", message);
  368. //}
  369. void httpServerHandleNotFound() {
  370. // if (strlen(http_user) > 0 && strlen(http_pass) > 0) {
  371. // if (!httpServer.authenticate(http_user, http_pass))
  372. // return httpServer.requestAuthentication();
  373. httpServer.send(404, "text/plain", "");
  374. //}
  375. }
  376. void httpServerInit() {
  377. httpServer.on("/delconf", []() {
  378. Serial.println("httpServer.on /delconf");
  379. if (httpServer.hasArg("token")) {
  380. char buf[20];
  381. httpServer.arg("token").toCharArray(buf, 20);
  382. if (strcmp(buf, CLEARCONF_TOKEN) == 0) {
  383. // httpServer.send(200, "text / plain", "Token OK - deleting config");
  384. deleteConfig();
  385. }
  386. } //if
  387. // else {
  388. // httpServer.send(200, "text / plain", "not allowed");
  389. // }
  390. });
  391. httpServer.on("/api", []() {
  392. DEBUG_PRINT("httpServer.on /api");
  393. if (httpServer.hasArg("plusBtn")) {
  394. setTempStepUp();
  395. DEBUG_PRINT(P("web plusBtn"));
  396. } //if
  397. if (httpServer.hasArg("minusBtn")) {
  398. setTempStepDown();
  399. DEBUG_PRINT(P("web minusBtn"));
  400. } //if
  401. if (httpServer.hasArg("modeBtn")) {
  402. toggleHeatingMode();
  403. DEBUG_PRINT(P("web modeBtn"));
  404. } //if
  405. if (httpServer.hasArg("onoffBtn")) {
  406. toggleThermostatOnOff();
  407. DEBUG_PRINT(P("web onoffBtn"));
  408. } //if
  409. //build json object of program data
  410. StaticJsonBuffer<200> jsonBuffer;
  411. JsonObject &json = jsonBuffer.createObject();
  412. json["devname"] = deviceName;
  413. json["ssid"] = WiFi.SSID();
  414. json["setTemp"] = setTemp;
  415. json["temp"] = currTemp;
  416. json["hum"] = int(currHum);
  417. json["mode"] = heatingMode;
  418. json["modeName"] = currentModeName;
  419. json["heating"] = turnHeatingOn;
  420. char jsonchar[200];
  421. json.printTo(jsonchar); //print to char array, takes more memory but sends in one piece
  422. httpServer.send(200, "application/json", jsonchar);
  423. }); //httpServer.on /api
  424. httpServer.on("/restart", []() {
  425. Serial.println("web triggered restart");
  426. ESP.restart();
  427. });
  428. httpServer.on("/mqttReconnect", []() {
  429. Serial.println("web triggered mqttReconnect");
  430. mqttReconnect();
  431. httpServer.sendHeader("Location", String("/"), true);
  432. httpServer.send (302, "text/plain", "OK");
  433. });
  434. httpServer.on("/setPoint", []() {
  435. if (httpServer.hasArg("token")) {
  436. char buf[20];
  437. httpServer.arg("token").toCharArray(buf, 20);
  438. if (strcmp(buf, http_token) == 0) {
  439. Serial.println("web triggered setPoint");
  440. if (httpServer.hasArg("value")) {
  441. char bufVal[20];
  442. httpServer.arg("value").toCharArray(bufVal, 20);
  443. float valueFloat = round(atof(bufVal) * 2.0) / 2.0;
  444. setTempTo(valueFloat);
  445. httpServer.send (200, "text/plain", "OK");
  446. }
  447. }
  448. } //if
  449. else {
  450. httpServer.send (403, "text/plain", "FORBIDDEN");
  451. }
  452. });
  453. httpServer.on("/setMode", []() {
  454. if (httpServer.hasArg("token")) {
  455. char buf[20];
  456. httpServer.arg("token").toCharArray(buf, 20);
  457. if (strcmp(buf, http_token) == 0) {
  458. Serial.println("web triggered setMode");
  459. if (httpServer.hasArg("value")) {
  460. char bufVal[20];
  461. httpServer.arg("value").toCharArray(bufVal, 20);
  462. int valueInt = atoi(bufVal);
  463. if(valueInt >= 0 && valueInt <= 3) setHeatingmodeTo(valueInt);
  464. httpServer.send (200, "text/plain", "OK");
  465. }
  466. }
  467. } //if
  468. else {
  469. httpServer.send (403, "text/plain", "FORBIDDEN");
  470. }
  471. });
  472. httpServer.on("/confdata", []() {
  473. boolean sendData = false;
  474. if (strlen(http_user) > 0 && strlen(http_pass) > 0) {
  475. if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication();
  476. sendData = true;
  477. }
  478. else sendData = true;
  479. if (sendData) {
  480. Serial.println("httpServer.on /confdata");
  481. for (int i = 0; i < httpServer.args(); i++) {
  482. char bufName[20];
  483. char bufValue[101];
  484. httpServer.argName(i).toCharArray(bufName, 20);
  485. httpServer.arg(i).toCharArray(bufValue, 101);
  486. if (strlen(bufName) > 0) {
  487. Serial.print("web update ");
  488. Serial.print(bufName);
  489. Serial.print(" = ");
  490. Serial.println(bufValue);
  491. setConfig(bufName, bufValue);
  492. }
  493. saveConfigToFlash = true; // will be saved in next loop()
  494. Serial.println("web triggered saveConfigToFlash");
  495. }
  496. yield();
  497. //build json object of program data
  498. StaticJsonBuffer<1000> jsonBuffer;
  499. JsonObject &json = jsonBuffer.createObject();
  500. json["devName"] = deviceName;
  501. json["httpUser"] = http_user;
  502. json["httpPass"] = http_pass;
  503. json["httpToken"] = http_token;
  504. json["mqttHost"] = mqtt_server;
  505. json["mqttPort"] = mqtt_port;
  506. json["mqttUser"] = mqtt_user;
  507. json["mqttPass"] = mqtt_pass;
  508. json["inTop"] = mqtt_topic_in;
  509. json["outTop"] = mqtt_topic_out;
  510. json["outRet"] = mqtt_outRetain;
  511. json["willTop"] = mqtt_willTopic;
  512. json["willQos"] = mqtt_willQos;
  513. json["willRet"] = mqtt_willRetain;
  514. json["willMsg"] = mqtt_willMsg;
  515. json["connMsg"] = mqtt_connMsg;
  516. json["domOutTop"] = domoticz_out_topic;
  517. yield();
  518. char jsonchar[1000];
  519. json.printTo(jsonchar); //print to char array, takes more memory but sends in one piece
  520. httpServer.send(200, "application/json", jsonchar);
  521. }
  522. }); //httpServer.on /confdata
  523. httpServer.on("/confdata2", []() {
  524. boolean sendData = false;
  525. if (strlen(http_user) > 0 && strlen(http_pass) > 0) {
  526. if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication();
  527. sendData = true;
  528. }
  529. else sendData = true;
  530. if (sendData) {
  531. Serial.println("httpServer.on /confdata2");
  532. for (int i = 0; i < httpServer.args(); i++) {
  533. char bufName[20];
  534. char bufValue[101];
  535. httpServer.argName(i).toCharArray(bufName, 20);
  536. httpServer.arg(i).toCharArray(bufValue, 101);
  537. if (strlen(bufName) > 0) {
  538. Serial.print("web update ");
  539. Serial.print(bufName);
  540. Serial.print(" = ");
  541. Serial.println(bufValue);
  542. setConfig(bufName, bufValue);
  543. }
  544. saveConfig2ToFlash = true;
  545. Serial.println("web triggered saveConfig2ToFlash");
  546. }
  547. yield();
  548. //build json object of program data
  549. StaticJsonBuffer<1000> jsonBuffer;
  550. JsonObject &json = jsonBuffer.createObject();
  551. json["domIdxTherm"] = domoticzIdx_Thermostat;
  552. json["domIdxMode"] = domoticzIdx_ThermostatMode;
  553. json["domIdxTempHum"] = domoticzIdx_TempHumSensor;
  554. json["domIdxHeating"] = domoticzIdx_Heating;
  555. json["domIdxPIR"] = domoticzIdx_PIR;
  556. json["outTempTop"] = outTemp_topic_in;
  557. json["outHumTop"] = outHum_topic_in;
  558. json["PIRTop"] = mqtt_topic_pir;
  559. json["autoSaveTemp"] = autoSaveSetTemp;
  560. json["autoSaveMode"] = autoSaveHeatingMode;
  561. json["minOffTime"] = heatingMinOffTime;
  562. json["tempMin"] = setTempMin;
  563. json["tempMax"] = setTempMax;
  564. json["tempLow"] = setTempLow;
  565. json["tempLow2"] = setTempLow2;
  566. json["tempDec"] = setTempDecreaseVal;
  567. json["hyst"] = hysteresis;
  568. json["tempCorr"] = tempCorrVal;
  569. json["humCorr"] = humCorrVal;
  570. json["measInt"] = measureInterval;
  571. json["dispInt"] = displayInterval;
  572. json["dispTout"] = displayTimeout;
  573. json["modename0"] = modename0;
  574. json["modename1"] = modename1;
  575. json["modename2"] = modename2;
  576. json["modename3"] = modename3;
  577. json["PIRenDisp"] = PIR_enablesDisplay;
  578. yield();
  579. char jsonchar[1000];
  580. json.printTo(jsonchar); //print to char array, takes more memory but sends in one piece
  581. httpServer.send(200, "application/json", jsonchar);
  582. }
  583. }); //httpServer.on /confdata2
  584. //get heap status, analog input value and all GPIO statuses in one json call
  585. httpServer.on("/info", HTTP_GET, []() {
  586. boolean sendData = false;
  587. if (strlen(http_user) > 0 && strlen(http_pass) > 0) {
  588. if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication();
  589. sendData = true;
  590. }
  591. else sendData = true;
  592. if (sendData) {
  593. String json = " {";
  594. json += "\"wifissid\":\"" + WiFi.SSID() + "\"";
  595. json += "\"heap\":" + String(ESP.getFreeHeap());
  596. json += "}";
  597. httpServer.send(200, "text/json", json);
  598. json = String();
  599. }
  600. }); //httpServer.on /info
  601. httpServer.on("/", []() {
  602. httpServerHandleRoot();
  603. });
  604. httpServer.on("/conf", []() {
  605. httpServerHandleConfPage();
  606. });
  607. httpServer.on("/conf2", []() {
  608. httpServerHandleConf2Page();
  609. });
  610. httpServer.onNotFound([]() {
  611. httpServerHandleNotFound();
  612. }); //httpServer.onNotFound
  613. // HTTP Updater at /update
  614. httpUpdater.setup(&httpServer);
  615. httpServer.begin();
  616. }