/* Created: 1-Nov-2021 14:27:23 Author: HS5TQA/Atten */ #include "AFSK.h" #include "webservice.h" #include "base64.hpp" #include // Web Server; WebServer server(80); String webString; bool defaultSetting = false; void serviceHandle() { server.handleClient(); } void setHTML(byte page) { webString = "\n"; webString += ""; webString += "\n"; if (page == 0) webString += " \n"; webString += " \n"; webString += "\n"; if (page == 0) { ///////////// google charts script webString += " \n"; webString += " \n"; } else if (page == 6) { webString += "\n"; webString += "\n"; webString += "\n"; webString += "\n"; } String strActiveP1 = ""; String strActiveP2 = ""; String strActiveP3 = ""; String strActiveP4 = ""; String strActiveP5 = ""; String strActiveP6 = ""; String strActiveP7 = ""; String strActiveP8 = ""; if (page == 7) strActiveP8 = "class=active"; else if (page == 6) strActiveP7 = "class=active"; else if (page == 5) strActiveP6 = "class=active"; else if (page == 4) strActiveP5 = "class=active"; else if (page == 3) strActiveP4 = "class=active"; else if (page == 2) strActiveP3 = "class=active"; else if (page == 1) strActiveP2 = "class=active"; else if (page == 0) strActiveP1 = "class=active"; webString += "\n"; webString += "
ESP32 APRS Internet Gateway
\n"; webString += "
\n"; webString += "
    \n"; webString += "
  • \nDash Board\n
  • \n"; #ifdef SDCARD webString += "
  • \nStorage\n
  • \n"; #endif webString += "
  • \nSetting\n
  • \n"; #ifdef SA818 webString += "
  • \nRadio\n
  • \n"; #endif webString += "
  • \nService\n
  • \n"; webString += "
  • \nSystem\n
  • \n"; webString += "
  • \nTest\n
  • \n"; webString += "
  • \nFirmware\n
  • \n"; webString += "
\n
"; if (page == 0) { char strTime[30]; struct tm tmstruct; tmstruct.tm_year = 0; time_t tn = now() - systemUptime; getLocalTime(&tmstruct, 5000); sprintf(strTime, "%d-%02d-%02d %02d:%02d:%02d", (tmstruct.tm_year) + 1900, (tmstruct.tm_mon) + 1, tmstruct.tm_mday, tmstruct.tm_hour, tmstruct.tm_min, tmstruct.tm_sec); webString += "
"; webString += "
Last Readings at " + String(strTime) + "
\n"; webString += "
CPU Temp: " + String((temprature_sens_read() - 32) / 1.8, 1) + "C
\n"; webString += "
Free Heap:" + String(ESP.getFreeHeap()) + " Byte
\n"; String uptime = String(day(tn) - 1, DEC) + "D " + String(hour(tn), DEC) + ":" + String(minute(tn), DEC) + ":" + String(second(tn), DEC); webString += "
System Uptime: " + uptime + "
\n"; webString += "
\n"; webString += "\n"; webString += "\n"; webString += "
WiFi Signal


\n"; webString += "
\n"; webString += "
STATISTICS
"; webString += ""; webString += ""; webString += ""; webString += ""; webString += ""; webString += ""; webString += "
ALL DATA" + String(status.allCount) + "
RF->INET" + String(status.rf2inet) + "
INET->RF" + String(status.inet2rf) + "
DROP" + String(status.dropCount) + "
ERROR" + String(status.errorCount) + "
"; webString += "
LAST STATION
"; webString += ""; sort(pkgList, PKGLISTSIZE); for (int i = 0; i < PKGLISTSIZE; i++) { if (pkgList[i].time > 0) { pkgList[i].calsign[10] = 0; time_t tm = pkgList[i].time; localtime_r(&pkgList[i].time, &tmstruct); String str = String(tmstruct.tm_hour, DEC) + ":" + String(tmstruct.tm_min, DEC) + ":" + String(tmstruct.tm_sec, DEC); // String str = String(hour(pkgList[i].time), DEC) + ":" + String(minute(pkgList[i].time), DEC) + ":" + String(second(pkgList[i].time), DEC); webString += ""; } } webString += "
" + String(pkgList[i].calsign) + "" + str + "
"; webString += "
TOP SEND
"; webString += ""; sortPkgDesc(pkgList, PKGLISTSIZE); for (int i = 0; i < PKGLISTSIZE; i++) { if (pkgList[i].time > 0) { pkgList[i].calsign[10] = 0; webString += ""; } } webString += "
" + String(pkgList[i].calsign) + "" + String(pkgList[i].pkg, DEC) + "
"; webString += "

\n"; } else if (page == 1) { // webString += "PAGE 2
\n"; } else if (page == 2) { // webString += "PAGE 3
\n"; } else if (page == 3) { } // webString += "\n"; } //////////////////////////////////////////////////////////// // handler for web server request: http://IpAddress/ // //////////////////////////////////////////////////////////// void handle_root() { setHTML(0); webString += "\n"; server.send(200, "text/html", webString); // send to someones browser when asked delay(100); webString.clear(); } #ifdef SDCARD void handle_storage() { String dirname = "/"; char strTime[100]; if (server.args() > 0) { for (uint8_t i = 0; i < server.args(); i++) { if (server.argName(i) == "SD_INIT") { // SD.end(); // if (!SD.begin(SDCARD_CS, spiSD, SDSPEED)) { // Serial.println("SD CARD Initialization failed!"); // //return; // } } } } setHTML(1); uint8_t cardType = SD.cardType(); webString += "SD CARD TYPE: "; if (cardType == CARD_NONE) { webString += "NOT FOUND\n"; } else { if (cardType == CARD_MMC) { webString += "MMC\n"; } else if (cardType == CARD_SD) { webString += "SDSC\n"; } else if (cardType == CARD_SDHC) { webString += "SDHC\n"; } else { webString += "UNKNOWN\n"; } unsigned long cardSize = SD.cardSize() / (1024 * 1024); unsigned long cardTotal = SD.totalBytes() / (1024 * 1024); unsigned long cardUsed = SD.usedBytes() / (1024 * 1024); webString += "
"; webString += "SD Card Size: "; webString += String((double)cardSize / 1000, 1) + "GB
\n"; webString += "Total space: "; webString += String((unsigned long)cardTotal) + "MB
\n"; webString += "Used space: "; webString += String((unsigned long)cardUsed) + "MB
\n"; webString += "

Listing directory:
" + dirname + "
\n"; File root = SD.open(dirname); if (!root) { webString += "Failed to open directory\n"; // return; } if (!root.isDirectory()) { webString += "Not a directory"; // return; } File file = root.openNextFile(); webString += ""; while (file) { if (file.isDirectory()) { // webString += ""; time_t t = file.getLastWrite(); struct tm *tmstruct = localtime(&t); sprintf(strTime, "", (tmstruct->tm_year) + 1900, (tmstruct->tm_mon) + 1, tmstruct->tm_mday, tmstruct->tm_hour, tmstruct->tm_min, tmstruct->tm_sec); webString += String(strTime); // if (levels) { // listDir(fs, file.name(), levels - 1); // } webString += "\n"; } else { /*Serial.print(" FILE: "); Serial.print(file.name());*/ String fName = String(file.name()).substring(1); webString += ""; // Serial.print(" SIZE: "); webString += ""; time_t t = file.getLastWrite(); struct tm *tmstruct = localtime(&t); sprintf(strTime, "", (tmstruct->tm_year) + 1900, (tmstruct->tm_mon) + 1, tmstruct->tm_mday, tmstruct->tm_hour, tmstruct->tm_min, tmstruct->tm_sec); webString += String(strTime); webString += "\n"; } file = root.openNextFile(); } webString += "
DIRECTORYFILE NAMESIZE(Byte)DATE TIMEDEL
DIR : "); webString += "
" + String(file.name()) + "%d-%02d-%02d %02d:%02d:%02d
/" + fName + "" + String(file.size()) + "%d-%02d-%02d %02d:%02d:%02dX
"; } webString += "
[SD INIT]
\n"; webString += "\n"; server.send(200, "text/html", webString); // send to someones browser when asked delay(100); } #endif void handle_setting() { // byte *ptr; bool synctime = false; // bool taretime = false; // bool davisEn = false; // bool moniEn = false; if (defaultSetting) { defaultConfig(); } else { #ifndef I2S_INTERNAL AFSK_TimerEnable(false); #endif if (server.args() > 0) { synctime = false; // taretime = false; for (uint8_t i = 0; i < server.args(); i++) { // Serial.print("SERVER ARGS "); // Serial.print(server.argName(i)); // Serial.print("="); // Serial.println(server.arg(i)); if (server.argName(i) == "synctime") { if (server.arg(i) != "") { // if (isValidNumber(server.arg(i))) if (String(server.arg(i)) == "OK") synctime = true; } } // if (server.argName(i) == "taretime") { // if (server.arg(i) != "") // { // //if (isValidNumber(server.arg(i))) // if (String(server.arg(i)) == "OK") // taretime = true; // } // } if (server.argName(i) == "gpsLat") { if (server.arg(i) != "") { config.gps_lat = server.arg(i).toFloat(); } } if (server.argName(i) == "gpsLon") { if (server.arg(i) != "") { config.gps_lon = server.arg(i).toFloat(); } } if (server.argName(i) == "gpsAlt") { if (server.arg(i) != "") { config.gps_alt = server.arg(i).toFloat(); } } if (server.argName(i) == "moniCall") { if (server.arg(i) != "") { strcpy(config.aprs_moniCall, server.arg(i).c_str()); } } if (server.argName(i) == "iconTable") { if (server.arg(i) != "") { config.aprs_table = *server.arg(i).c_str(); } } if (server.argName(i) == "iconSymbol") { if (server.arg(i) != "") { config.aprs_symbol = *server.arg(i).c_str(); } } if (server.argName(i) == "aprsPath") { if (server.arg(i) != "") { strcpy(config.tnc_path, server.arg(i).c_str()); } } if (server.argName(i) == "beaconIntv") { if (server.arg(i) != "") { if (isValidNumber(server.arg(i))) config.aprs_beacon = server.arg(i).toInt(); } } if (server.argName(i) == "comment") { if (server.arg(i) != "") { strcpy(config.aprs_comment, server.arg(i).c_str()); } } } config.synctime = synctime; saveEEPROM(); // topBar(WiFi.RSSI()); } #ifndef I2S_INTERNAL AFSK_TimerEnable(true); #endif } // getMoisture(); // read sensor // webMessage = ""; setHTML(2); webString += "
\n"; webString += "
\n"; webString += "
\n

Fix Location

\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; String syncFlage = ""; if (config.synctime) syncFlage = "checked"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; // div general webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; server.send(200, "text/html", webString); // send to someones browser when asked } void handle_service() { bool aprsEn = false; bool tncEn = false; bool digiEn = false; bool tlmEn = false; bool rf2inetEn = false; bool inet2rfEn = false; bool hpfEn = false; if (server.hasArg("commit")) { #ifndef I2S_INTERNAL AFSK_TimerEnable(false); #endif for (uint8_t i = 0; i < server.args(); i++) { // Serial.print("SERVER ARGS "); // Serial.print(server.argName(i)); // Serial.print("="); // Serial.println(server.arg(i)); if (server.argName(i) == "aprsEnable") { if (server.arg(i) != "") { if (String(server.arg(i)) == "OK") aprsEn = true; } } if (server.argName(i) == "myCall") { if (server.arg(i) != "") { strcpy(config.aprs_mycall, server.arg(i).c_str()); } } if (server.argName(i) == "myobject") { if (server.arg(i) != "") { strcpy(config.aprs_object, server.arg(i).c_str()); // for (int i = strlen(config.aprs_object); i < 9; i++) { config.aprs_object[i] = 0x20; } // config.aprs_object[9] = 0; } else { config.aprs_object[0] = 0; } } if (server.argName(i) == "mySSID") { if (server.arg(i) != "") { if (isValidNumber(server.arg(i))) config.aprs_ssid = server.arg(i).toInt(); if (config.aprs_ssid > 15) config.aprs_ssid = 13; } } if (server.argName(i) == "myPasscode") { if (server.arg(i) != "") { strcpy(config.aprs_passcode, server.arg(i).c_str()); } } if (server.argName(i) == "aprsHost") { if (server.arg(i) != "") { strcpy(config.aprs_host, server.arg(i).c_str()); } } if (server.argName(i) == "aprsPort") { if (server.arg(i) != "") { if (isValidNumber(server.arg(i))) config.aprs_port = server.arg(i).toInt(); } } if (server.argName(i) == "aprsFilter") { if (server.arg(i) != "") { strcpy(config.aprs_filter, server.arg(i).c_str()); } } // if (server.argName(i) == "aprsComment") { // if (server.arg(i) != "") // { // strcpy(config.tnc_comment, server.arg(i).c_str()); // } // } if (server.argName(i) == "tncEnable") { if (server.arg(i) != "") { if (String(server.arg(i)) == "OK") tncEn = true; } } if (server.argName(i) == "digiEnable") { if (server.arg(i) != "") { if (String(server.arg(i)) == "OK") digiEn = true; } } if (server.argName(i) == "tlmEnable") { if (server.arg(i) != "") { if (String(server.arg(i)) == "OK") tlmEn = true; } } if (server.argName(i) == "rf2inetEnable") { if (server.arg(i) != "") { if (String(server.arg(i)) == "OK") rf2inetEn = true; } } if (server.argName(i) == "inet2rfEnable") { if (server.arg(i) != "") { if (String(server.arg(i)) == "OK") inet2rfEn = true; } } if (server.argName(i) == "hpfEnable") { if (server.arg(i) != "") { if (String(server.arg(i)) == "OK") hpfEn = true; } } if (server.argName(i) == "digiDelay") { if (server.arg(i) != "") { if (isValidNumber(server.arg(i))) config.digi_delay = server.arg(i).toInt(); if (config.digi_delay > 5000) config.digi_delay = 5000; } } if (server.argName(i) == "timeSlot") { if (server.arg(i) != "") { if (isValidNumber(server.arg(i))) config.tx_timeslot = server.arg(i).toInt(); if (config.tx_timeslot > 10000) config.tx_timeslot = 10000; } } // if (server.argName(i) == "mqttEnable") { // if (server.arg(i) != "") // { // if (String(server.arg(i)) == "OK") // mqttEn = true; // } // } // if (server.argName(i) == "mqttHost") { // if (server.arg(i) != "") // { // strcpy(config.mqtt_host, server.arg(i).c_str()); // } // } // if (server.argName(i) == "mqttPort") { // if (server.arg(i) != "") // { // if (isValidNumber(server.arg(i))) // config.mqtt_port = server.arg(i).toInt(); // } // } } config.aprs = aprsEn; config.tnc = tncEn; config.tnc_digi = digiEn; config.tnc_telemetry = tlmEn; config.rf2inet = rf2inetEn; config.inet2rf = inet2rfEn; config.input_hpf = hpfEn; input_HPF = hpfEn; saveEEPROM(); // if(config.tnc) tncInit(); #ifndef I2S_INTERNAL AFSK_TimerEnable(true); #endif } // getMoisture(); // read sensor // webMessage = ""; setHTML(3); webString += "
\n"; webString += "
\n"; webString += "
\n

APRS Setting

\n"; webString += "
\n"; webString += "\n"; String aprsFlage = ""; if (config.aprs) aprsFlage = "checked"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; // webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
From Here
\n"; webString += "
\n"; // webString += "
\n"; // webString += "\n"; // webString += "
\n"; // webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "

Web Service: T2THAI
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; String tncFlage = ""; if (config.tnc) tncFlage = "checked"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; String tlmFlage = ""; if (config.tnc_telemetry) tlmFlage = "checked"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; String rf2inetFlage = ""; if (config.rf2inet) rf2inetFlage = "checked"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; String inet2rfFlage = ""; if (config.inet2rf) inet2rfFlage = "checked"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; String hpfFlage = ""; if (config.input_hpf) hpfFlage = "checked"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; String digiFlage = ""; if (config.tnc_digi) digiFlage = "checked"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "
\n
\n"; // div aprs webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; server.send(200, "text/html", webString); // send to someones browser when asked } #ifdef SA818 void handle_radio() { // bool noiseEn=false; // bool agcEn=false; if (server.hasArg("commit")) { for (uint8_t i = 0; i < server.args(); i++) { // Serial.print("SERVER ARGS "); // Serial.print(server.argName(i)); // Serial.print("="); // Serial.println(server.arg(i)); // if (server.argName(i) == "agcCheck") // { // if (server.arg(i) != "") // { // if (String(server.arg(i)) == "OK") // { // agcEn=true; // } // } // } if (server.argName(i) == "nw_band") { if (server.arg(i) != "") { if (isValidNumber(server.arg(i))) { config.band = server.arg(i).toInt(); // if (server.arg(i).toInt()) // config.band = 1; // else // config.band = 0; } } } if (server.argName(i) == "volume") { if (server.arg(i) != "") { if (isValidNumber(server.arg(i))) config.volume = server.arg(i).toInt(); } } if (server.argName(i) == "rf_power") { if (server.arg(i) != "") { if (isValidNumber(server.arg(i))) { if (server.arg(i).toInt()) config.rf_power = true; else config.rf_power = false; } } } if (server.argName(i) == "sql_level") { if (server.arg(i) != "") { if (isValidNumber(server.arg(i))) config.sql_level = server.arg(i).toInt(); } } if (server.argName(i) == "tx_freq") { if (server.arg(i) != "") { if (isValidNumber(server.arg(i))) config.freq_tx = server.arg(i).toFloat(); } } if (server.argName(i) == "rx_freq") { if (server.arg(i) != "") { if (isValidNumber(server.arg(i))) config.freq_rx = server.arg(i).toFloat(); } } if (server.argName(i) == "tx_offset") { if (server.arg(i) != "") { if (isValidNumber(server.arg(i))) config.offset_tx = server.arg(i).toInt(); } } if (server.argName(i) == "rx_offset") { if (server.arg(i) != "") { if (isValidNumber(server.arg(i))) config.offset_rx = server.arg(i).toInt(); } } if (server.argName(i) == "tx_ctcss") { if (server.arg(i) != "") { if (isValidNumber(server.arg(i))) config.tone_tx = server.arg(i).toInt(); } } if (server.argName(i) == "rx_ctcss") { if (server.arg(i) != "") { if (isValidNumber(server.arg(i))) config.tone_rx = server.arg(i).toInt(); } } } // config.noise=noiseEn; // config.agc=agcEn; saveEEPROM(); // delay(100); SA818_INIT(false); } setHTML(7); webString += "
\n"; webString += "
\n"; webString += "
\n

RF Module SA818/SA868

\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; // webString += "
\n"; // webString += "\n"; // webString += "
\n"; // webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; // webString += "
\n"; // webString += "\n"; // webString += "
\n"; // webString += "
\n"; String cmSelSqlT = ""; String cmSelSqlF = ""; if (config.band) { cmSelSqlT = "selected"; } else { cmSelSqlF = "selected"; } webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; cmSelSqlF = ""; cmSelSqlT = ""; if (config.rf_power) { cmSelSqlT = "selected"; } else { cmSelSqlF = "selected"; } webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
" + String(config.volume) + "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
" + String(config.sql_level) + "
\n"; webString += "
\n"; // webString += "
\n"; // webString += "\n"; // webString += "
" + String(config.mic) + "
\n"; // webString += "
\n"; // webString += "
\n"; // webString += "\n"; // String agcFlage = ""; // if (config.agc) // agcFlage = "checked"; // webString += "
\n"; // webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; // webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; server.send(200, "text/html", webString); // send to someones browser when asked // delay(100); } #endif void handle_system() { if (server.hasArg("updateTimeNtp")) { for (uint8_t i = 0; i < server.args(); i++) { // Serial.print("SERVER ARGS "); // Serial.print(server.argName(i)); // Serial.print("="); // Serial.println(server.arg(i)); if (server.argName(i) == "SetTimeNtp") { if (server.arg(i) != "") { Serial.println("WEB Config NTP"); configTime(3600 * timeZone, 0, server.arg(i).c_str()); } break; } } saveEEPROM(); } else if (server.hasArg("updateTime")) { for (uint8_t i = 0; i < server.args(); i++) { // Serial.print("SERVER ARGS "); // Serial.print(server.argName(i)); // Serial.print("="); // Serial.println(server.arg(i)); if (server.argName(i) == "SetTime") { if (server.arg(i) != "") { // struct tm tmn; String date = getValue(server.arg(i), ' ', 0); String time = getValue(server.arg(i), ' ', 1); int yyyy = getValue(date, '-', 0).toInt(); int mm = getValue(date, '-', 1).toInt(); int dd = getValue(date, '-', 2).toInt(); int hh = getValue(time, ':', 0).toInt(); int ii = getValue(time, ':', 1).toInt(); int ss = getValue(time, ':', 2).toInt(); // int ss = 0; tmElements_t timeinfo; timeinfo.Year = yyyy - 1970; timeinfo.Month = mm; timeinfo.Day = dd; timeinfo.Hour = hh; timeinfo.Minute = ii; timeinfo.Second = ss; time_t timeStamp = makeTime(timeinfo); // tmstruct.tm_year) + 1900, (tmstruct.tm_mon) + 1, tmstruct.tm_mday, tmstruct.tm_hour, tmstruct.tm_min, tmstruct.tm_sec time_t rtc = timeStamp - 25200; timeval tv = {rtc, 0}; timezone tz = {TZ_SEC + DST_MN, 0}; settimeofday(&tv, &tz); // Serial.println("Update TIME " + server.arg(i)); Serial.print("Set New Time at "); Serial.print(dd); Serial.print("/"); Serial.print(mm); Serial.print("/"); Serial.print(yyyy); Serial.print(" "); Serial.print(hh); Serial.print(":"); Serial.print(ii); Serial.print(":"); Serial.print(ss); Serial.print(" "); Serial.println(timeStamp); } break; } } saveEEPROM(); } else if (server.hasArg("updateWifi")) { bool wifiSTA = false; bool wifiAP = false; for (uint8_t i = 0; i < server.args(); i++) { if (server.argName(i) == "wifiAP") { if (server.arg(i) != "") { if (String(server.arg(i)) == "OK") { wifiAP = true; } } } if (server.argName(i) == "wificlient") { if (server.arg(i) != "") { if (String(server.arg(i)) == "OK") { wifiSTA = true; } } } if (server.argName(i) == "gpsLat") { if (server.arg(i) != "") { config.gps_lat = server.arg(i).toFloat(); } } if (server.argName(i) == "gpsLon") { if (server.arg(i) != "") { config.gps_lon = server.arg(i).toFloat(); } } if (server.argName(i) == "gpsAlt") { if (server.arg(i) != "") { config.gps_alt = server.arg(i).toFloat(); } } if (server.argName(i) == "wifi_ssidAP") { if (server.arg(i) != "") { strcpy(config.wifi_ap_ssid, server.arg(i).c_str()); } } if (server.argName(i) == "wifi_passAP") { if (server.arg(i) != "") { strcpy(config.wifi_ap_pass, server.arg(i).c_str()); } } if (server.argName(i) == "wifi_ssid") { if (server.arg(i) != "") { strcpy(config.wifi_ssid, server.arg(i).c_str()); } } if (server.argName(i) == "wifi_pass") { if (server.arg(i) != "") { strcpy(config.wifi_pass, server.arg(i).c_str()); } } if (server.argName(i) == "wifi_pwr") { if (server.arg(i) != "") { if (isValidNumber(server.arg(i))) config.wifi_power = server.arg(i).toInt(); } } } if (wifiAP && wifiSTA) { config.wifi_mode = WIFI_AP_STA_FIX; } else if (wifiAP) { config.wifi_mode = WIFI_AP_FIX; } else if (wifiSTA) { config.wifi_mode = WIFI_STA_FIX; } else { config.wifi_mode = WIFI_OFF_FIX; } saveEEPROM(); } struct tm tmstruct; char strTime[20]; tmstruct.tm_year = 0; getLocalTime(&tmstruct, 5000); sprintf(strTime, "%d-%02d-%02d %02d:%02d:%02d", (tmstruct.tm_year) + 1900, (tmstruct.tm_mon) + 1, tmstruct.tm_mday, tmstruct.tm_hour, tmstruct.tm_min, tmstruct.tm_sec); // webMessage = ""; setHTML(4); // webString += "
\n"; webString += "\n"; webString += "\n"; webString += "\n"; webString += ""; webString += "
\n

TIME Setting

\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; // webString += "
\n"; webString += "\n"; webString += "\n\n\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "\n"; webString += "\n\n
" + String(strTime) + "
\n"; webString += "\n\n
\n"; webString += "
\n"; webString += "

\n"; webString += "
\n"; webString += "
\n

WiFi Network

\n"; webString += "
\n"; webString += "\n"; String wifiFlageAP = ""; if ((config.wifi_mode == WIFI_AP_STA_FIX) || (config.wifi_mode == WIFI_AP_FIX)) wifiFlageAP = "checked"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "

\n"; webString += "
\n"; webString += "\n"; String wifiFlage = ""; if (config.wifi_client) wifiFlage = "checked"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "
\n

WiFi Status

\n"; webString += "
\n"; webString += "\n"; webString += "\n"; webString += "\n"; webString += "\n"; webString += "\n"; webString += "\n"; webString += "\n"; webString += "\n"; webString += "\n"; webString += "\n"; webString += "\n"; webString += "\n"; webString += "\n"; webString += "\n"; webString += "\n"; webString += "\n"; webString += "\n"; webString += "
Mode:"; if (config.wifi_mode == WIFI_AP_FIX) { webString += "AP"; } else if (config.wifi_mode == WIFI_STA_FIX) { webString += "STA"; } else if (config.wifi_mode == WIFI_AP_STA_FIX) { webString += "AP+STA"; } else { webString += "OFF"; } wifi_power_t wpr = WiFi.getTxPower(); String wifipower = ""; if (wpr < 8) { wifipower = "-1 dBm"; } else if (wpr < 21) { wifipower = "2 dBm"; } else if (wpr < 29) { wifipower = "5 dBm"; } else if (wpr < 35) { wifipower = "8.5 dBm"; } else if (wpr < 45) { wifipower = "11 dBm"; } else if (wpr < 53) { wifipower = "13 dBm"; } else if (wpr < 61) { wifipower = "15 dBm"; } else if (wpr < 69) { wifipower = "17 dBm"; } else if (wpr < 75) { wifipower = "18.5 dBm"; } else if (wpr < 77) { wifipower = "19 dBm"; } else if (wpr < 80) { wifipower = "19.5 dBm"; } else { wifipower = "20 dBm"; } webString += "
MAC:" + String(WiFi.macAddress()) + "
Channel:" + String(WiFi.channel()) + "
TX Power:" + String(WiFi.getTxPower()) + "
SSID:" + String(WiFi.SSID()) + "
Local IP:" + WiFi.localIP().toString() + "
Gateway IP:" + WiFi.gatewayIP().toString() + "
DNS:" + WiFi.dnsIP().toString() + "
\n"; webString += "

\n"; webString += "\n"; webString += "\n"; server.send(200, "text/html", webString); // send to someones browser when asked delay(100); } extern bool afskSync; extern String lastPkgRaw; extern float dBV; extern int mVrms; void handle_realtime() { // char jsonMsg[1000]; char *jsonMsg; time_t timeStamp; time(&timeStamp); if (afskSync && (lastPkgRaw.length() > 5)) { int input_length = lastPkgRaw.length(); jsonMsg = (char *)malloc((input_length * 2) + 70); char *input_buffer = (char *)malloc(input_length + 2); char *output_buffer = (char *)malloc(input_length * 2); if (output_buffer) { lastPkgRaw.toCharArray(input_buffer, lastPkgRaw.length(), 0); lastPkgRaw.clear(); encode_base64((unsigned char *)input_buffer, input_length, (unsigned char *)output_buffer); // Serial.println(output_buffer); sprintf(jsonMsg, "{\"Active\":\"1\",\"mVrms\":\"%d\",\"RAW\":\"%s\",\"timeStamp\":\"%li\"}", mVrms, output_buffer, timeStamp); // Serial.println(jsonMsg); free(input_buffer); free(output_buffer); } } else { jsonMsg = (char *)malloc(100); if (afskSync) sprintf(jsonMsg, "{\"Active\":\"1\",\"mVrms\":\"%d\",\"RAW\":\"REVDT0RFIEZBSUwh\",\"timeStamp\":\"%li\"}", mVrms, timeStamp); else sprintf(jsonMsg, "{\"Active\":\"0\",\"mVrms\":\"0\",\"RAW\":\"\",\"timeStamp\":\"%li\"}", timeStamp); } afskSync = false; server.send(200, "text/html", String(jsonMsg)); delay(100); free(jsonMsg); } void handle_test() { if (server.hasArg("sendBeacon")) { String tnc2Raw = send_fix_location(); if (config.tnc) pkgTxUpdate(tnc2Raw.c_str(), 0); // APRS_sendTNC2Pkt(tnc2Raw); // Send packet to RF } else if (server.hasArg("sendRaw")) { for (uint8_t i = 0; i < server.args(); i++) { if (server.argName(i) == "raw") { if (server.arg(i) != "") { String tnc2Raw = server.arg(i); if (config.tnc) { pkgTxUpdate(tnc2Raw.c_str(), 0); // APRS_sendTNC2Pkt(server.arg(i)); // Send packet to RF // Serial.println("Send RAW: " + tnc2Raw); } } break; } } } setHTML(6); webString += "\n"; webString += "\n"; webString += "\n"; webString += "\n"; webString += "\n"; webString += "
\n"; webString += "

\n"; webString += "
TNC2 RAW: APE32I,WIDE1-1:>Test Status\"/>
\n"; webString += "
\n"; webString += "

Terminal
\n"; webString += "\n"; server.send(200, "text/html", webString); // send to someones browser when asked delay(100); } void handle_firmware() { char strCID[50]; uint64_t chipid = ESP.getEfuseMac(); sprintf(strCID, "%04X%08X", (uint16_t)(chipid >> 32), (uint32_t)chipid); // webMessage = ""; setHTML(5); webString += "\n"; webString += "Current Hardware Version: ESP32DR Simple\n
"; webString += "Current Firmware Version: V" + String(VERSION) + "\n
"; webString += "Develop by: HS5TQA\n
"; webString += "Chip ID: " + String(strCID) + "\n
"; webString += "
\n

Firmware Update

\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; // webString += "
\n"; // webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += "
\n"; webString += ""; webString += "\n"; server.send(200, "text/html", webString); // send to someones browser when asked delay(100); } void handle_default() { defaultSetting = true; defaultConfig(); // webMessage = ""; handle_setting(); defaultSetting = false; } #ifdef SDCARD void handle_download() { String dataType = "text/plain"; String path; if (server.args() > 0) { for (uint8_t i = 0; i < server.args(); i++) { if (server.argName(i) == "FILE") { path = server.arg(i); break; } } } if (path.endsWith(".src")) path = path.substring(0, path.lastIndexOf(".")); else if (path.endsWith(".htm")) dataType = "text/html"; else if (path.endsWith(".csv")) dataType = "text/csv"; else if (path.endsWith(".css")) dataType = "text/css"; else if (path.endsWith(".xml")) dataType = "text/xml"; else if (path.endsWith(".png")) dataType = "image/png"; else if (path.endsWith(".gif")) dataType = "image/gif"; else if (path.endsWith(".jpg")) dataType = "image/jpeg"; else if (path.endsWith(".ico")) dataType = "image/x-icon"; else if (path.endsWith(".svg")) dataType = "image/svg+xml"; else if (path.endsWith(".ico")) dataType = "image/x-icon"; else if (path.endsWith(".js")) dataType = "application/javascript"; else if (path.endsWith(".pdf")) dataType = "application/pdf"; else if (path.endsWith(".zip")) dataType = "application/zip"; else if (path.endsWith(".gz")) { if (path.startsWith("/gz/htm")) dataType = "text/html"; else if (path.startsWith("/gz/css")) dataType = "text/css"; else if (path.startsWith("/gz/csv")) dataType = "text/csv"; else if (path.startsWith("/gz/xml")) dataType = "text/xml"; else if (path.startsWith("/gz/js")) dataType = "application/javascript"; else if (path.startsWith("/gz/svg")) dataType = "image/svg+xml"; else dataType = "application/x-gzip"; } // webString = "\n"; // webString += " \n"; // webMessage += "\n"; // webString += "\n"; File myFile = SD.open("/" + path, "r"); if (myFile) { server.sendHeader("Content-Type", dataType); server.sendHeader("Content-Disposition", "attachment; filename=" + path); server.sendHeader("Connection", "close"); server.streamFile(myFile, "application/octet-stream"); myFile.close(); } delay(100); } void handle_delete() { String dataType = "text/plain"; String path; if (server.args() > 0) { for (uint8_t i = 0; i < server.args(); i++) { if (server.argName(i) == "FILE") { path = server.arg(i); Serial.println("Deleting file: " + path); if (SD.remove("/" + path)) { Serial.println("File deleted"); } else { Serial.println("Delete failed"); } break; } } } handle_storage(); } void listDir(fs::FS &fs, const char *dirname, uint8_t levels) { Serial.printf("Listing directory: %s\n", dirname); File root = fs.open(dirname); if (!root) { Serial.println("Failed to open directory"); return; } if (!root.isDirectory()) { Serial.println("Not a directory"); return; } File file = root.openNextFile(); while (file) { if (file.isDirectory()) { Serial.print(" DIR : "); Serial.print(file.name()); time_t t = file.getLastWrite(); struct tm *tmstruct = localtime(&t); Serial.printf(" LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct->tm_year) + 1900, (tmstruct->tm_mon) + 1, tmstruct->tm_mday, tmstruct->tm_hour, tmstruct->tm_min, tmstruct->tm_sec); if (levels) { listDir(fs, file.name(), levels - 1); } } else { Serial.print(" FILE: "); Serial.print(file.name()); Serial.print(" SIZE: "); Serial.print(file.size()); time_t t = file.getLastWrite(); struct tm *tmstruct = localtime(&t); Serial.printf(" LAST WRITE: %d-%02d-%02d %02d:%02d:%02d\n", (tmstruct->tm_year) + 1900, (tmstruct->tm_mon) + 1, tmstruct->tm_mday, tmstruct->tm_hour, tmstruct->tm_min, tmstruct->tm_sec); } file = root.openNextFile(); } } #endif void webService() { server.close(); // web client handlers server.on("/", handle_root); server.on("/config", handle_setting); #ifdef SDCARD server.on("/data", handle_storage); server.on("/download", handle_download); server.on("/delete", handle_delete); #endif #ifdef SA818 server.on("/radio", handle_radio); #endif server.on("/default", handle_default); server.on("/service", handle_service); server.on("/system", handle_system); server.on("/test", handle_test); server.on("/realtime", handle_realtime); server.on("/firmware", handle_firmware); /*handling uploading firmware file */ server.on( "/update", HTTP_POST, []() { server.sendHeader("Connection", "close"); server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK"); ESP.restart(); }, []() { HTTPUpload &upload = server.upload(); if (upload.status == UPLOAD_FILE_START) { Serial.printf("Firmware Update FILE: %s\n", upload.filename.c_str()); if (!Update.begin(UPDATE_SIZE_UNKNOWN)) { // start with max available size Update.printError(Serial); delay(3); } else { // wdtDisplayTimer = millis(); // wdtSensorTimer = millis(); disableCore0WDT(); disableCore1WDT(); disableLoopWDT(); i2s_adc_disable(I2S_NUM_0); dac_i2s_disable(); vTaskSuspend(taskAPRSHandle); // vTaskSuspend(taskNetworkHandle); config.aprs = false; config.tnc = false; #ifndef I2S_INTERNAL AFSK_TimerEnable(false); #endif delay(3); } } else if (upload.status == UPLOAD_FILE_WRITE) { /* flashing firmware to ESP*/ if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) { Update.printError(Serial); delay(3); } } else if (upload.status == UPLOAD_FILE_END) { if (Update.end(true)) { // true to set the size to the current progress delay(3); } else { Update.printError(Serial); delay(3); } } }); server.begin(); }