httpServer.ino 21 KB

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