Snorktracker
 All Data Structures Files Functions Variables Macros Pages
WebServer.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2018 SFini
3 
4  This program is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
25 #include <ESP8266WiFi.h>
26 #include <ESP8266WebServer.h>
27 #include <DNSServer.h>
28 #include "Spiffs.h"
29 #include "HtmlTag.h"
30 
34 class MyESPWebServer : public ESP8266WebServer
35 {
36 public:
37  MyESPWebServer(int port = 80)
38  : ESP8266WebServer(port) { }
39 
40  WiFiClient &wifiClient() { return _currentClient; }
41 };
42 
48 {
49 public:
51  static IPAddress ip;
52  static DNSServer dnsServer;
53  static MyOptions *myOptions;
54  static MyData *myData;
55 
56 protected:
57  static bool loadFromSpiffs (String path);
58  static void AddTableBegin (String &info);
59  static void AddTableTr (String &info);
60  static void AddTableTr (String &info, String name, String value);
61  static void AddTableEnd (String &info);
62  static bool GetOption (String id, String &option);
63  static bool GetOption (String id, long &option);
64  static bool GetOption (String id, double &option);
65  static bool GetOption (String id, bool &option);
66  static void AddBr (String &info);
67  static void AddOption (String &info, String id, String name, bool value, bool addBr = true);
68  static void AddOption (String &info, String id, String name, String value, bool addBr = true, bool isPassword = false);
69  static void AddIntervalInfo (String &info);
70 
71 public:
72  static void handleRoot();
73  static void loadMain();
74  static void handleLoadMainInfo();
75  static void loadUpdate();
76  static void loadSettings();
77  static void handleLoadSettingsInfo();
78  static void handleSaveSettings();
79  static void handleLoadInfoInfo();
80  static void loadConsole();
81  static void handleLoadConsoleInfo();
82  static void loadRestart();
83  static void handleLoadRestartInfo();
84  static void handleNotFound();
85  static void handleWebRequests();
86 
87 public:
89 
90 public:
91  MyWebServer(MyOptions &options, MyData &data);
92  ~MyWebServer();
93 
94  bool begin();
95  void handleClient();
96 };
97 
98 /* ******************************************** */
99 
100 IPAddress MyWebServer::ip(192, 168, 1, 1);
101 DNSServer MyWebServer::dnsServer;
105 
106 
109  : isWebServerActive(false)
110 {
111  myOptions = &options;
112  myData = &data;
113 }
114 MyWebServer::~MyWebServer()
115 {
116  myOptions = NULL;
117  myData = NULL;
118 }
119 
125 {
126  if (!myOptions || !myData) {
127  return false;
128  }
129 
130  MyDbg(F("MyWebServer::begin"));
131  WiFi.persistent(false);
132  WiFi.mode(WIFI_AP_STA);
133  WiFi.softAP(SOFT_AP_NAME, SOFT_AP_PW);
134  WiFi.softAPConfig(ip, ip, IPAddress(255, 255, 255, 0));
135  dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
136  dnsServer.start(53, F("*"), ip);
137  myData->softAPIP = WiFi.softAPIP().toString();
138  myData->softAPmacAddress = WiFi.softAPmacAddress();
139  MyDbg((String) F("SoftAPIP address: ") + myData->softAPIP, true);
140  MyDbg((String) F("SoftAPIP mac address: ") + myData->softAPmacAddress, true);
141 
142  if (myOptions->connectWifiAP) {
143  WiFi.begin(myOptions->wifiAP.c_str(), myOptions->wifiPassword.c_str());
144  for (int i = 0; i < 30 && WiFi.status() != WL_CONNECTED; i++) { // 30 Sec versuchen
145  MyDbg(F("."), true, false);
146  MyDelay(1000);
147  }
148  }
149  if (WiFi.status() == WL_CONNECTED) {
150  myData->stationIP = WiFi.localIP().toString();
151  MyDbg((String) F("Connected to ") + myOptions->wifiAP, true);
152  MyDbg((String) F("Station IP address: ") + myData->stationIP, true);
153  MyDbg((String) F("AP1 SSID (RSSI): ") + String(myOptions->wifiAP + F(" (") + WifiGetRssiAsQuality(WiFi.RSSI()) + F("%)")));
154  } else { // switch to AP Mode only
155  if (myOptions->connectWifiAP) {
156  MyDbg((String) F("No connection to ") + myOptions->wifiAP, true);
157  }
158  WiFi.disconnect();
159  WiFi.mode(WIFI_AP);
160  }
161 
162  server.on(F("/"), handleRoot);
163  server.on(F("/Main.html"), loadMain);
164  server.on(F("/MainInfo"), handleLoadMainInfo);
165  server.on(F("/Update.html"), loadUpdate);
166  server.on(F("/Settings.html"), loadSettings);
167  server.on(F("/SettingsInfo"), handleLoadSettingsInfo);
168  server.on(F("/SaveSettings"), handleSaveSettings);
169  server.on(F("/InfoInfo"), handleLoadInfoInfo);
170  server.on(F("/Console.html"), loadConsole);
171  server.on(F("/ConsoleInfo"), handleLoadConsoleInfo);
172  server.on(F("/Restart.html"), loadRestart);
173  server.on(F("/RestartInfo"), handleLoadRestartInfo);
174  server.onNotFound(handleWebRequests);
175 
176  server.begin();
177  MyDbg(F("Server listening"), true);
178 
179  isWebServerActive = true;
180  return true;
181 }
182 
185 {
186  if (isWebServerActive) {
187  server.handleClient();
188  dnsServer.processNextRequest();
189  }
190 }
191 
193 void MyWebServer::AddTableBegin(String &info)
194 {
195  info += F("<table style='width:100%'>");
196 }
197 
199 void MyWebServer::AddTableTr(String &info)
200 {
201  info += F("<tr><th></th><td>&nbsp;</td></tr>");
202 }
203 
205 void MyWebServer::AddTableTr(String &info, String name, String value)
206 {
207  if (value != "") {
208  info += F("<tr>");
209  info += (String) F("<th>") + TextToXml(name) + F("</th>");
210  info += (String) F("<td>") + TextToXml(value) + F("</td>");
211  info += F("</tr>");
212  }
213 }
214 
216 void MyWebServer::AddTableEnd(String &info)
217 {
218  info += F("</table>");
219 }
220 
222 bool MyWebServer::GetOption(String id, String &option)
223 {
224  if (server.hasArg(id)) {
225  option = server.arg(id);
226  return true;
227  }
228  return false;
229 }
230 
232 bool MyWebServer::GetOption(String id, long &option)
233 {
234  bool ret = false;
235  String opt = server.arg(id);
236 
237  if (opt != "") {
238  if (opt.indexOf(F(":")) != -1) {
239  ret = scanInterval(opt, option);
240  } else {
241  option = atoi(opt.c_str());
242  ret = true;
243  }
244  }
245  return ret;
246 }
247 
249 bool MyWebServer::GetOption(String id, double &option)
250 {
251  String opt = server.arg(id);
252 
253  if (opt != "") {
254  option = atof(opt.c_str());
255  return true;
256  }
257  return false;
258 }
259 
261 bool MyWebServer::GetOption(String id, bool &option)
262 {
263  String opt = server.arg(id);
264 
265  option = false;
266  if (opt != "") {
267  if (opt == F("on")) {
268  option = true;
269  }
270  return true;
271  }
272  return false;
273 }
274 
276 void MyWebServer::AddBr(String &info)
277 {
278  info += F("<br />");
279 }
280 
282 void MyWebServer::AddOption(String &info, String id, String name, String value, bool addBr /* = true */, bool isPassword /* = false */)
283 {
284  info += (String) F("<b>") + TextToXml(name) + F("</b>");
285  info += (String) F("<input id='") + id + F("' name='") + id + F("' ");
286  /*
287  * Autocomplete overwrites our password if the type is password :(
288  * So we show it actually in clear text.
289  if (isPassword) {
290  info += " type='password' autocomplete='new-password' ";
291  }
292  */
293  info += (String) F("value='") + TextToXml(value) + F("'>");
294  if (addBr) {
295  info += F("<br />");
296  }
297 }
298 
300 void MyWebServer::AddOption(String &info, String id, String name, bool value, bool addBr /* = true */)
301 {
302  info += F("<input style='width:auto;' id='");
303  info += id;
304  info += F("' name='");
305  info += id;
306  info += F("' type='checkbox' ");
307  info += value ? F(" checked") : F("");
308  info += F("><b>");
309  info += TextToXml(name);
310  info += F("</b>");
311  if (addBr) {
312  info += F("<br />");
313  }
314 }
315 
318 {
319  info += (String) F("<p>") + TextToXml(F("Interval in '[days] hours:minutes:seconds' or just 'seconds'")) + F("</p>");
320  info += F("<br />");
321 }
322 
325 {
326  bool ret = false;
327 
328  String dataType = F("text/plain");
329  if(path.endsWith("/")) path += F("index.htm");
330 
331  if(path.endsWith(F(".src"))) path = path.substring(0, path.lastIndexOf("."));
332  else if(path.endsWith(F(".html"))) dataType = F("text/html");
333  else if(path.endsWith(F(".htm"))) dataType = F("text/html");
334  else if(path.endsWith(F(".css"))) dataType = F("text/css");
335  else if(path.endsWith(F(".js"))) dataType = F("application/javascript");
336  else if(path.endsWith(F(".png"))) dataType = F("image/png");
337  else if(path.endsWith(F(".gif"))) dataType = F("image/gif");
338  else if(path.endsWith(F(".jpg"))) dataType = F("image/jpeg");
339  else if(path.endsWith(F(".ico"))) dataType = F("image/x-icon");
340  else if(path.endsWith(F(".xml"))) dataType = F("text/xml");
341  else if(path.endsWith(F(".pdf"))) dataType = F("application/pdf");
342  else if(path.endsWith(F(".zip"))) dataType = F("application/zip");
343 
344  File dataFile = SPIFFS.open(path.c_str(), "r");
345  if (dataFile) {
346  if (server.hasArg(F("download"))) {
347  dataType = F("application/octet-stream");
348  }
349  if (server.streamFile(dataFile, dataType) == dataFile.size()) {
350  ret = true;
351  }
352  dataFile.close();
353  }
354  return ret;
355 }
356 
359 {
360  server.sendHeader(F("Location"), F("Main.html"), true);
361  server.send(302, F("text/plain"), "");
362 }
363 
366 {
367  if (loadFromSpiffs(F("/Main.html"))) {
368  return;
369  }
370  handleNotFound();
371 }
372 
375 {
376  if (!myOptions || !myData) {
377  return;
378  }
379 
380  String info;
381  String onOff = server.arg(F("o"));
382 
383  if (onOff == F("1")) {
385  myOptions->save();
386  }
387 
388  AddTableBegin(info);
389  if (myData->status != "") {
390  AddTableTr(info, F("Status"), myData->status);
391  }
392 #ifdef SIM808_CONNECTED
393  AddTableTr(info, F("Modem Info"), myData->modemInfo);
394 #else
395  if (WiFi.status() != WL_CONNECTED) {
396  AddTableTr(info, F("AP SSID"), String(SOFT_AP_NAME));
397  } else {
398  AddTableTr(info, F("AP SSID (RSSI)"), String(myOptions->wifiAP + F(" (") + WifiGetRssiAsQuality(WiFi.RSSI()) + F("%)")));
399  }
400  AddTableTr(info);
401 #endif
402 
403  AddTableTr(info, F("Battery"), String(myData->voltage, 2) + F(" V"));
404  AddTableTr(info, F("Temperature"), String(myData->temperature, 1) + F(" °C"));
405  AddTableTr(info, F("Humidity"), String(myData->humidity, 1) + F(" %"));
406  AddTableTr(info, F("Pressure"), String(myData->pressure, 1) + F(" hPa"));
407 #ifndef SIM808_CONNECTED
408  AddTableTr(info, F("Active Time"), formatInterval(myData->getActiveTimeSec()));
409  AddTableTr(info, F("PowerUpTime"), formatInterval(myData->getPowerOnTimeSec()));
410  AddTableTr(info, F("DeepSleepTime"), formatInterval(myData->rtcData.deepSleepTimeSec));
411  AddTableTr(info, F("mAh"), String(myData->getPowerConsumption(), 2));
412  AddTableTr(info, F("Low power mAh"), String(myData->getLowPowerPowerConsumption(), 2));
413 #endif
415  AddTableTr(info, F("Longitude"), myData->rtcData.lastGps.longitudeString());
416  AddTableTr(info, F("Latitude"), myData->rtcData.lastGps.latitudeString());
417  AddTableTr(info, F("Altitude"), myData->rtcData.lastGps.altitudeString() + F(" m"));
418  AddTableTr(info, F("Speed"), myData->rtcData.lastGps.kmphString() + F(" kmph"));
419  AddTableTr(info, F("Satellites"), myData->rtcData.lastGps.satellitesString());
420  }
421 
422  if (myOptions->isMqttEnabled) {
423  MyTime mqttLastSentTime(myData->rtcData.mqttLastSentTime);
424 
425  AddTableTr(info, F("MQTT sent"), String(myData->rtcData.mqttSendCount));
426 #ifdef SIM808_CONNECTED
427  AddTableTr(info, F("MQTT last"), mqttLastSentTime.timeString());
428 #endif
429  }
430 
431  if (myData->secondsToDeepSleep >= 0) {
432  AddTableTr(info, F("Power saving in "), String(myData->secondsToDeepSleep) + F(" Seconds"));
433  }
434  AddTableEnd(info);
435 
436  info += (String)
437  F("<table style='width:100%'>"
438  "<tr>"
439  "<td style='width:100%'>"
440  "<div style='text-align:center;font-weight:bold;font-size:62px'>") +
441  + (myOptions->powerOn ? F("ON") : F("OFF")) +
442  F("</div>"
443  "</td>"
444  "</tr>"
445  "</table>");
446 
447  server.send(200, F("text/html"), info);
448 }
449 
452 {
453  if (!myOptions || !myData) {
454  return;
455  }
456  if (!myData->isOtaActive) {
457  SetupOTA();
458  ArduinoOTA.begin();
459  myData->isOtaActive = true;
460  }
461 
462  if (loadFromSpiffs(F("/Update.html"))) {
463  return;
464  }
465  handleNotFound();
466 }
467 
470 {
471  if (loadFromSpiffs(F("/Settings.html"))) {
472  return;
473  }
474  handleNotFound();
475 }
476 
479 {
480  if (!myOptions || !myData) {
481  return;
482  }
483 
484  String info;
485 
486  MyDbg(F("LoadSettings"), true);
487 
488  AddOption(info, F("isDebugActive"), F("Debug Active"), myOptions->isDebugActive);
489 
490  AddOption(info, F("bme280CheckIntervalSec"), F("Temperature check every (Interval)"), formatInterval(myOptions->bme280CheckIntervalSec));
491 
492 #ifdef SIM808_CONNECTED
493  AddOption(info, F("gprsAP"), F("GPRS AP"), myOptions->gprsAP);
494  AddOption(info, F("gprsUser"), F("GPRS User"), myOptions->gprsUser);
495  AddOption(info, F("gprsPassword"), F("GPRS Password"), myOptions->gprsPassword);
496 #endif
497 
498  AddBr(info);
499  {
500  HtmlTag fieldset(info, F("fieldset"));
501  {
502  HtmlTag legend(info, F("legend"));
503 
504  AddOption(info, F("connectWifiAP"), F("WiFi connect"), myOptions->connectWifiAP, false);
505  }
506 
507  AddOption(info, F("wifiAP"), F("WiFi SSID"), myOptions->wifiAP, false);
508  AddOption(info, F("wifiPassword"), F("WiFi Password"), myOptions->wifiPassword, false, true);
509  }
510 
511 #ifdef SIM808_CONNECTED
512  AddBr(info);
513  {
514  HtmlTag fieldset(info, F("fieldset"));
515  {
516  HtmlTag legend(info, F("legend"));
517 
518  AddOption(info, F("isSmsEnabled"), F("SMS Enabled"), myOptions->isSmsEnabled, false);
519  }
520 
521  AddOption(info, F("smsCheckIntervalSec"), F("SMS check every (Interval)"), formatInterval(myOptions->smsCheckIntervalSec));
522  AddOption(info, F("phoneNumber"), F("Information send to"), myOptions->phoneNumber, false);
523  }
524  AddBr(info);
525  {
526  HtmlTag fieldset(info, F("fieldset"));
527  {
528  HtmlTag legend(info, F("legend"));
529 
530  AddOption(info, F("isGpsEnabled"), F("GPS Enabled"), myOptions->isGpsEnabled, false);
531  }
532  AddOption(info, F("gpsCheckIntervalSec"), F("GPS check every (Interval)"), formatInterval(myOptions->gpsCheckIntervalSec));
533  AddOption(info, F("gpsTimeoutSec"), F("GPS timeout"), formatInterval(myOptions->gpsTimeoutSec));
534  AddOption(info, F("minMovingDistance"), F("GPS is moving if more than (meter)"), String(myOptions->minMovingDistance), false);
535  }
536 #endif
537 
538  AddBr(info);
539  {
540  HtmlTag fieldset(info, F("fieldset"));
541  {
542  HtmlTag legend(info, F("legend"));
543 
544  AddOption(info, F("isMqttEnabled"), F("MQTT Active"), myOptions->isMqttEnabled, false);
545  }
546 
547  AddOption(info, F("mqttName"), F("MQTT Name"), myOptions->mqttName);
548  AddOption(info, F("mqttId"), F("MQTT Id"), myOptions->mqttId);
549 
550  AddOption(info, F("mqttServer"), F("MQTT Server"), myOptions->mqttServer);
551  AddOption(info, F("mqttPort"), F("MQTT Port"), String(myOptions->mqttPort));
552  AddOption(info, F("mqttUser"), F("MQTT User"), myOptions->mqttUser);
553  AddOption(info, F("mqttPassword"), F("MQTT Password"), myOptions->mqttPassword, true, true);
554 #ifdef SIM808_CONNECTED
555  AddOption(info, F("mqttSendOnMoveEverySec"), F("MQTT Send on moving every (Interval)"), formatInterval(myOptions->mqttSendOnMoveEverySec));
556  AddOption(info, F("mqttSendOnNonMoveEverySec"), F("MQTT Send on standing every (Interval)"), formatInterval(myOptions->mqttSendOnNonMoveEverySec), false);
557 #else
558  AddOption(info, F("mqttSendOnNonMoveEverySec"), F("MQTT Send every (Interval)"), formatInterval(myOptions->mqttSendOnNonMoveEverySec), false);
559 #endif
560  }
561 
562  AddBr(info);
563  {
564  HtmlTag fieldset(info, F("fieldset"));
565  {
566  HtmlTag legend(info, F("legend"));
567 
568  AddOption(info, F("isDeepSleepEnabled"), F("Power saving mode active"), myOptions->isDeepSleepEnabled, false);
569  }
570  AddOption(info, F("powerSaveModeVoltage"), F("Power saving mode below (Volt)"), String(myOptions->powerSaveModeVoltage, 2));
571  AddOption(info, F("powerCheckIntervalSec"), F("Check power every (Interval)"), formatInterval(myOptions->powerCheckIntervalSec));
572 
573  AddOption(info, F("activeTimeSec"), F("Active time (Interval)"), formatInterval(myOptions->activeTimeSec));
574  AddOption(info, F("deepSleepTimeSec"), F("DeepSleep time (Interval)"), formatInterval(myOptions->deepSleepTimeSec), false);
575  }
576 
577  AddIntervalInfo(info);
578 
579  server.send(200, F("text/html"), info);
580 }
581 
584 {
585  if (!myOptions || !myData) {
586  return;
587  }
588 
589  MyDbg(F("SaveSettings"), true);
590  GetOption(F("gprsAP"), myOptions->gprsAP);
591  GetOption(F("gprsUser"), myOptions->gprsUser);
592  GetOption(F("gprsPassword"), myOptions->gprsPassword);
593  GetOption(F("connectWifiAP"), myOptions->connectWifiAP);
594  GetOption(F("wifiAP"), myOptions->wifiAP);
595  GetOption(F("wifiPassword"), myOptions->wifiPassword);
596  GetOption(F("isDebugActive"), myOptions->isDebugActive);
597  GetOption(F("bme280CheckIntervalSec"), myOptions->bme280CheckIntervalSec);
598  GetOption(F("isSmsEnabled"), myOptions->isSmsEnabled);
599  GetOption(F("phoneNumber"), myOptions->phoneNumber);
600  GetOption(F("smsCheckIntervalSec"), myOptions->smsCheckIntervalSec);
601  GetOption(F("isGpsEnabled"), myOptions->isGpsEnabled);
602  GetOption(F("gpsTimeoutSec"), myOptions->gpsTimeoutSec);
603  GetOption(F("gpsCheckIntervalSec"), myOptions->gpsCheckIntervalSec);
604  GetOption(F("minMovingDistance"), myOptions->minMovingDistance);
605  GetOption(F("isDeepSleepEnabled"), myOptions->isDeepSleepEnabled);
606  GetOption(F("powerSaveModeVoltage"), myOptions->powerSaveModeVoltage);
607  GetOption(F("powerCheckIntervalSec"), myOptions->powerCheckIntervalSec);
608  GetOption(F("activeTimeSec"), myOptions->activeTimeSec);
609  GetOption(F("deepSleepTimeSec"), myOptions->deepSleepTimeSec);
610  GetOption(F("isMqttEnabled"), myOptions->isMqttEnabled);
611  GetOption(F("mqttName"), myOptions->mqttName);
612  GetOption(F("mqttId"), myOptions->mqttId);
613  GetOption(F("mqttServer"), myOptions->mqttServer);
614  GetOption(F("mqttPort"), myOptions->mqttPort);
615  GetOption(F("mqttUser"), myOptions->mqttUser);
616  GetOption(F("mqttPassword"), myOptions->mqttPassword);
617  GetOption(F("mqttSendOnMoveEverySec"), myOptions->mqttSendOnMoveEverySec);
618  GetOption(F("mqttSendOnNonMoveEverySec"), myOptions->mqttSendOnNonMoveEverySec);
619 
620  // Reset the rtc data if something has changed.
621  myData->awakeTimeOffsetSec = millis() / 1000;
622  myOptions->save();
623 
624  if (false /* reboot */) {
625  myData->restartInfo =
626  F("<b>Settings saved</b>");
627  loadRestart();
628  }
629  loadMain();
630 }
631 
634 {
635  if (!myOptions || !myData) {
636  return;
637  }
638 
639  String info;
640  String ssidRssi = (String) myOptions->wifiAP + F(" (") + WifiGetRssiAsQuality(WiFi.RSSI()) + F("%)");
641 
642  AddTableBegin(info);
643  if (myData->status != "") {
644  AddTableTr(info, F("Status"), myData->status);
645  AddTableTr(info);
646  }
647  if (myData->isOtaActive) {
648  AddTableTr(info, F("OTA"), F("Active"));
649  AddTableTr(info);
650  }
651  if (ssidRssi != "" || myData->softAPIP || myData->softAPmacAddress != "" || myData->stationIP != "") {
652  AddTableTr(info, F("AP1 SSID (RSSI)"), ssidRssi);
653  AddTableTr(info, F("AP IP"), myData->softAPIP);
654  AddTableTr(info, F("Locale IP"), myData->stationIP);
655  AddTableTr(info, F("MAC Address"), myData->softAPmacAddress);
656  AddTableTr(info);
657  }
658 #ifdef SIM808_CONNECTED
659  if (myData->modemInfo != "" || myData->modemIP != "" || myData->imei != "" || myData->cop != "" ||
660  myData->signalQuality != "" || myData->batteryLevel != "" || myData->batteryVolt != "") {
661  AddTableTr(info, F("Modem Info"), myData->modemInfo);
662  AddTableTr(info, F("Modem IP"), myData->modemIP);
663  AddTableTr(info, F("IMEI"), myData->imei);
664  AddTableTr(info, F("COP"), myData->cop);
665  AddTableTr(info, F("Signal Quality"), myData->signalQuality);
666  AddTableTr(info, F("Battery Level"), myData->batteryLevel);
667  AddTableTr(info, F("Battery Volt"), myData->batteryVolt);
668  AddTableTr(info);
669  }
671  AddTableTr(info, F("Longitude"), myData->rtcData.lastGps.longitudeString());
672  AddTableTr(info, F("Latitude"), myData->rtcData.lastGps.latitudeString());
673  AddTableTr(info, F("Altitude"), myData->rtcData.lastGps.altitudeString());
674  AddTableTr(info, F("Km/h"), myData->rtcData.lastGps.kmphString());
675  AddTableTr(info, F("Satellite"), myData->rtcData.lastGps.satellitesString());
676  AddTableTr(info, F("Course"), myData->rtcData.lastGps.courseString());
677  AddTableTr(info, F("GPS Date"), myData->rtcData.lastGps.date.dateString());
678  AddTableTr(info, F("GPS Time"), myData->rtcData.lastGps.time.timeString());
679  AddTableTr(info);
680  }
681  if (myData->isMoving || myData->movingDistance != 0.0) {
682  AddTableTr(info, F("Moving"), myData->isMoving ? F("Yes") : F("No"));
683  AddTableTr(info, F("Distance (m)"), String(myData->movingDistance, 2));
684  AddTableTr(info);
685  }
686  AddTableTr(info, F("Active Time"), formatInterval(myData->getActiveTimeSec()));
687  AddTableTr(info, F("PowerUpTime"), formatInterval(myData->getPowerOnTimeSec()));
688  AddTableTr(info, F("DeepSleepTime"), formatInterval(myData->rtcData.deepSleepTimeSec));
689  AddTableTr(info, F("mAh"), String(myData->getPowerConsumption(), 2));
690  AddTableTr(info, F("Low power mAh"), String(myData->getLowPowerPowerConsumption(), 2));
691  AddTableTr(info);
692 #endif
693  AddTableTr(info, F("ESP Chip ID"), String(ESP.getChipId()));
694  AddTableTr(info, F("Flash Chip ID"), String(ESP.getFlashChipId()));
695  AddTableTr(info, F("Real Flash Memory"), String(ESP.getFlashChipRealSize()) + F(" Byte"));
696  AddTableTr(info, F("Total Flash Memory"), String(ESP.getFlashChipSize()) + F(" Byte"));
697  AddTableTr(info, F("Used Flash Memory"), String(ESP.getSketchSize()) + F(" Byte"));
698  AddTableTr(info, F("Free Sketch Memory"), String(ESP.getFreeSketchSpace()) + F(" Byte"));
699  AddTableTr(info, F("Free Heap Memory"), String(ESP.getFreeHeap()) + F(" Byte"));
700 
701  AddTableEnd(info);
702 
703  server.send(200, F("text/html"), info);
704 }
705 
708 {
709  if (loadFromSpiffs(F("/Console.html"))) {
710  if (server.hasArg(F("clear"))) {
712  }
713  return;
714  }
715  handleNotFound();
716 }
717 
720 {
721  if (!myOptions || !myData) {
722  return;
723  }
724 
725  String sendData;
726  String cmd = server.arg(F("c1"));
727  String startIdx = server.arg(F("c2"));
728 
729  if (server.hasArg(F("c1"))) {
730  MyDbg(cmd, true);
731  myData->consoleCmds.addTail(cmd);
732  }
733 
734  int indexFrom = atoi(startIdx.c_str()) - myData->logInfos.rolledOut();
735 
736  sendData = (String)
737  F("<r>"
738  "<i>") + String(myData->logInfos.count() + myData->logInfos.rolledOut()) + F("</i>"
739  "<j>1</j>"
740  "<l>");
741  for (int i = indexFrom; i < myData->logInfos.count(); i++) {
742  if (i >= 0 && i < myData->logInfos.count()) {
743  sendData += TextToUrl(myData->logInfos.getAt(i));
744  sendData += '\n';
745  }
746  }
747  sendData += (String)
748  F("</l>"
749  "</r>");
750 
751  server.send(200, F("text/xml"), sendData.c_str());
752 }
753 
756 {
757  if (loadFromSpiffs(F("/Restart.html"))) {
758  MyDbg(F("Load File /Restart.html"), true);
759  MyDelay(2000);
760  MyDbg(F("Restart"), true);
761  ESP.restart();
762  return;
763  }
764  handleNotFound();
765 }
766 
769 {
770  if (!myOptions || !myData) {
771  return;
772  }
773 
774  server.send(200, F("text/html"), myData->restartInfo);
775  myData->restartInfo = "";
776 }
777 
780 {
781  if (!myOptions || !myData) {
782  return;
783  }
784 
785  String message = F("File Not Found\n");
786 
787  message += F("URI: ");
788  message += server.uri();
789  message += F("\nMethod: ");
790  message += (server.method() == HTTP_GET) ? F("GET") : F("POST");
791  message += F("\nArguments: ");
792  message += server.args();
793  message += F("\n");
794  // Better no debuggin of browser args
795  // for (uint8_t i=0; i<server.args(); i++){
796  // message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
797  // }
798  server.send(404, F("text/plain"), message);
799  MyDbg(message, true);
800 }
801 
804 {
805  if (loadFromSpiffs(server.uri())) {
806  return;
807  }
808  handleNotFound();
809 }
String formatInterval(long secs)
Definition: Utils.h:191
long deepSleepTimeSec
Time to stay in deep sleep (without check interrupts)
Definition: Options.h:53
static void AddTableBegin(String &info)
Definition: WebServer.h:193
String phoneNumber
Pone number for sms answers.
Definition: Options.h:47
static DNSServer dnsServer
Dns server.
Definition: WebServer.h:52
static void handleLoadRestartInfo()
Definition: WebServer.h:768
int rolledOut()
Definition: StringList.h:78
bool isGpsEnabled
Is the gps part of the sim808 active?
Definition: Options.h:43
double powerSaveModeVoltage
Minimum voltage to stay always alive.
Definition: Options.h:50
bool scanInterval(String interval, long &secs)
Definition: Utils.h:210
long smsCheckIntervalSec
SMS check intervall.
Definition: Options.h:48
static void handleNotFound()
Definition: WebServer.h:779
bool begin()
Definition: WebServer.h:124
static void handleLoadConsoleInfo()
Definition: WebServer.h:719
bool connectWifiAP
Should we connect to wifi.
Definition: Options.h:36
static void loadSettings()
Definition: WebServer.h:469
long awakeTimeOffsetSec
Awake time offset for SaveSettings.
Definition: Data.h:72
String TextToXml(String data)
Definition: Utils.h:156
static bool loadFromSpiffs(String path)
Definition: WebServer.h:324
String mqttUser
MQTT user.
Definition: Options.h:59
static MyData * myData
Reference to the data.
Definition: WebServer.h:54
String status
Status information.
Definition: Data.h:63
class MyData::RtcData rtcData
Data to store in the RTC memory.
StringList consoleCmds
open commands to send to the sim808 module
Definition: Data.h:97
double getLowPowerPowerConsumption()
Definition: Data.h:241
static void handleLoadInfoInfo()
Definition: WebServer.h:633
void SetupOTA()
Definition: Utils.h:264
String wifiAP
WiFi AP name.
Definition: Options.h:37
static void handleRoot()
Definition: WebServer.h:358
long gpsCheckIntervalSec
Time interval to check the gps position.
Definition: Options.h:45
static void handleLoadMainInfo()
Definition: WebServer.h:374
Definition: Data.h:27
StringList logInfos
received sim808 answers or other logs
Definition: Data.h:98
String TextToUrl(String data)
Definition: Utils.h:137
static void loadMain()
Definition: WebServer.h:365
void MyDbg(String info, bool fromWebServer=false, bool newline=true)
Definition: Utils.h:94
String softAPIP
registered ip of the access point
Definition: Data.h:79
#define SOFT_AP_NAME
Soft access point name.
Definition: Config.h:26
void removeAll()
Definition: StringList.h:84
static void loadUpdate()
Definition: WebServer.h:451
String imei
IMEI of the sim card.
Definition: Data.h:85
long mqttLastSentTime
Last mqtt sent timestamp.
Definition: Data.h:51
bool powerOn
Is the GSM power from the DC-DC modul switched on?
Definition: Options.h:41
void handleClient()
Definition: WebServer.h:184
String mqttId
MQTT ID.
Definition: Options.h:56
double temperature
Current BME280 temperature.
Definition: Data.h:75
long gpsTimeoutSec
Timeout for waiting for gps position.
Definition: Options.h:44
MyGps lastGps
Last known gps location without timeout.
Definition: Data.h:35
String mqttPassword
MQTT password.
Definition: Options.h:60
String altitudeString()
Definition: Gps.h:552
int count()
Definition: StringList.h:72
double getPowerConsumption()
Definition: Data.h:231
String WifiGetRssiAsQuality(int rssi)
Definition: Utils.h:119
String satellitesString()
Definition: Gps.h:564
void MyDelay(long millisDelay)
Definition: Utils.h:104
static void loadRestart()
Definition: WebServer.h:755
static void AddTableTr(String &info)
Definition: WebServer.h:199
double pressure
Current BME280 pressure.
Definition: Data.h:77
static MyOptions * myOptions
Reference to the options.
Definition: WebServer.h:53
String dateString()
Definition: Gps.h:355
String signalQuality
Quality of the signal.
Definition: Data.h:87
long powerCheckIntervalSec
Time interval to check the power supply.
Definition: Options.h:51
static void AddBr(String &info)
Definition: WebServer.h:276
String wifiPassword
WiFi AP password.
Definition: Options.h:38
bool isWebServerActive
Is the webserver currently active.
Definition: WebServer.h:88
String courseString()
Definition: Gps.h:570
String gprsUser
GRPS access point User.
Definition: Options.h:34
String longitudeString()
Definition: Gps.h:540
String kmphString()
Definition: Gps.h:558
String batteryVolt
Battery volt of the sim808 module.
Definition: Data.h:89
static void handleLoadSettingsInfo()
Definition: WebServer.h:478
String mqttServer
MQTT server url.
Definition: Options.h:57
static void AddIntervalInfo(String &info)
Definition: WebServer.h:317
long mqttSendCount
How many time the mqtt data successfully sent.
Definition: Data.h:50
bool isDebugActive
Is detailed debugging enabled?
Definition: Options.h:39
long mqttPort
MQTT server port.
Definition: Options.h:58
static MyESPWebServer server
Webserver helper class.
Definition: WebServer.h:50
static bool GetOption(String id, String &option)
Definition: WebServer.h:222
String restartInfo
Information on restart.
Definition: Data.h:64
static IPAddress ip
Soft AP ip Address.
Definition: WebServer.h:51
long activeTimeSec
Maximum alive time after deepsleep.
Definition: Options.h:52
static void handleWebRequests()
Definition: WebServer.h:803
String cop
Operator selection.
Definition: Data.h:86
long getPowerOnTimeSec()
Definition: Data.h:209
long bme280CheckIntervalSec
Time interval to read the temp, hum and pressure.
Definition: Options.h:40
String stationIP
registered station ip
Definition: Data.h:81
bool isMoving
Is moving recognized.
Definition: Data.h:94
String getAt(int idx)
Definition: StringList.h:92
double voltage
Current supply voltage.
Definition: Data.h:74
String gprsPassword
GRPS access point Password.
Definition: Options.h:35
String batteryLevel
Battery level of the sim808 module.
Definition: Data.h:88
MyDate date
The received gps utc date.
Definition: Gps.h:134
static void AddTableEnd(String &info)
Definition: WebServer.h:216
bool isSmsEnabled
Is the sms check functionality active?
Definition: Options.h:42
String modemInfo
Information from SIM808.
Definition: Data.h:83
bool save()
Definition: Options.h:209
#define SOFT_AP_PW
Soft access point password.
Definition: Config.h:27
String softAPmacAddress
module mac address
Definition: Data.h:80
String latitudeString()
Definition: Gps.h:546
String modemIP
registered modem ip
Definition: Data.h:84
long secondsToDeepSleep
Time until next deepsleep. -1 = disabled.
Definition: Data.h:71
void addTail(String newInfo)
Definition: StringList.h:112
String gprsAP
GRPS access point of the sim card supplier.
Definition: Options.h:33
String mqttName
MQTT server name.
Definition: Options.h:55
static void handleSaveSettings()
Definition: WebServer.h:583
bool isMqttEnabled
Should the system connect to a MQTT server?
Definition: Options.h:54
static void AddOption(String &info, String id, String name, bool value, bool addBr=true)
Definition: WebServer.h:300
Definition: Gps.h:97
long deepSleepTimeSec
Time in deep sleep mode.
Definition: Data.h:39
MyTime time
The received gps utc time.
Definition: Gps.h:135
bool fixStatus
Are the gps is valid received?
Definition: Gps.h:133
MyWebServer(MyOptions &options, MyData &data)
Definition: WebServer.h:108
double humidity
Current BME280 humidity.
Definition: Data.h:76
bool isOtaActive
Is OverTheAir update active?
Definition: Data.h:65
long mqttSendOnNonMoveEverySec
Send data interval to MQTT server on non moving.
Definition: Options.h:62
bool isDeepSleepEnabled
Should the system go into deepsleep if needed.
Definition: Options.h:49
static void loadConsole()
Definition: WebServer.h:707
String timeString()
Definition: Gps.h:385
long mqttSendOnMoveEverySec
Send data interval to MQTT server on moving.
Definition: Options.h:61
long getActiveTimeSec()
Definition: Data.h:193
double movingDistance
Minimum distance for moving flag.
Definition: Data.h:95
long minMovingDistance
Minimum distance to accept as moving or not.
Definition: Options.h:46