Files
arduino-libs/arduino-cli/libraries/ESP_WiFiManager/examples/ESP32_FSWebServer/ESP32_FSWebServer.ino
2024-07-20 22:09:06 +08:00

861 lines
24 KiB
C++

/****************************************************************************************************************************
ESP32_FSWebServer - Example WebServer with SPIFFS backend for esp8266
For ESP32 boards
ESP_WiFiManager is a library for the ESP8266/ESP32 platform (https://github.com/esp8266/Arduino) to enable easy
configuration and reconfiguration of WiFi credentials using a Captive Portal.
Modified from Tzapu https://github.com/tzapu/WiFiManager
and from Ken Taylor https://github.com/kentaylor
Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager
Licensed under MIT license
Example modified from https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WebServer/examples/FSBrowser/FSBrowser.ino
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
This file is part of the ESP8266WebServer library for Arduino environment.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Version: 1.2.0
Version Modified By Date Comments
------- ----------- ---------- -----------
1.0.0 K Hoang 07/10/2019 Initial coding
1.0.1 K Hoang 13/12/2019 Fix bug. Add features. Add support for ESP32
1.0.2 K Hoang 19/12/2019 Fix bug thatkeeps ConfigPortal in endless loop if Portal/Router SSID or Password is NULL.
1.0.3 K Hoang 05/01/2020 Option not displaying AvailablePages in Info page. Enhance README.md. Modify examples
1.0.4 K Hoang 07/01/2020 Add RFC952 setHostname feature.
1.0.5 K Hoang 15/01/2020 Add configurable DNS feature. Thanks to @Amorphous of https://community.blynk.cc
1.0.6 K Hoang 03/02/2020 Add support for ArduinoJson version 6.0.0+ ( tested with v6.14.1 )
1.0.7 K Hoang 13/04/2020 Reduce start time, fix SPIFFS bug in examples, update README.md
1.0.8 K Hoang 10/06/2020 Fix STAstaticIP issue. Restructure code. Add LittleFS support for ESP8266 core 2.7.1+
1.0.9 K Hoang 29/07/2020 Fix ESP32 STAstaticIP bug. Permit changing from DHCP <-> static IP using Config Portal.
Add, enhance examples (fix MDNS for ESP32)
1.0.10 K Hoang 08/08/2020 Add more features to Config Portal. Use random WiFi AP channel to avoid conflict.
1.0.11 K Hoang 17/08/2020 Add CORS feature. Fix bug in softAP, autoConnect, resetSettings.
1.1.0 K Hoang 28/08/2020 Add MultiWiFi feature to autoconnect to best WiFi at runtime
1.1.1 K Hoang 30/08/2020 Add setCORSHeader function to allow flexible CORS. Fix typo and minor improvement.
1.1.2 K Hoang 17/08/2020 Fix bug. Add example.
1.2.0 K Hoang 09/10/2020 Restore cpp code besides Impl.h code to use if linker error. Fix bug.
*****************************************************************************************************************************/
/*****************************************************************************************************************************
How To Use:
1) Upload the contents of the data folder with MkSPIFFS Tool ("ESP32 Sketch Data Upload" in Tools menu in Arduino IDE)
2) or you can upload the contents of a folder if you CD in that folder and run the following command:
for file in `\ls -A1`; do curl -F "file=@$PWD/$file" esp32-fs-browser.local/edit; done
3) access the sample web page at http://esp32-fs-browser.local
4) edit the page by going to http://esp32-fs-browser.local/edit
*****************************************************************************************************************************/
#if !defined(ESP32)
#error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
#endif
// Use from 0 to 4. Higher number, more debugging messages and memory usage.
#define _WIFIMGR_LOGLEVEL_ 3
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>
// From v1.1.0
#include <WiFiMulti.h>
WiFiMulti wifiMulti;
//////
// You only need to format the filesystem once
//#define FORMAT_FILESYSTEM true
#define FORMAT_FILESYSTEM false
#define USE_SPIFFS true
#if USE_SPIFFS
#include <SPIFFS.h>
FS* filesystem = &SPIFFS;
#define FileFS SPIFFS
#define FS_Name "SPIFFS"
#else
// Use FFat
#include <FFat.h>
FS* filesystem = &FFat;
#define FileFS FFat
#define FS_Name "FFat"
#endif
#define DBG_OUTPUT_PORT Serial
// SSID and PW for Config Portal
String ssid = "ESP_" + String((uint32_t)ESP.getEfuseMac(), HEX);
const char* password = "your_password";
// SSID and PW for your Router
String Router_SSID;
String Router_Pass;
// From v1.1.0
#define MIN_AP_PASSWORD_SIZE 8
#define SSID_MAX_LEN 32
//From v1.0.10, WPA2 passwords can be up to 63 characters long.
#define PASS_MAX_LEN 64
typedef struct
{
char wifi_ssid[SSID_MAX_LEN];
char wifi_pw [PASS_MAX_LEN];
} WiFi_Credentials;
typedef struct
{
String wifi_ssid;
String wifi_pw;
} WiFi_Credentials_String;
#define NUM_WIFI_CREDENTIALS 2
typedef struct
{
WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS];
} WM_Config;
WM_Config WM_config;
#define CONFIG_FILENAME F("/wifi_cred.dat")
//////
// Indicates whether ESP has WiFi credentials saved from previous session, or double reset detected
bool initialConfig = false;
// Use false if you don't like to display Available Pages in Information Page of Config Portal
// Comment out or use true to display Available Pages in Information Page of Config Portal
// Must be placed before #include <ESP_WiFiManager.h>
#define USE_AVAILABLE_PAGES false
// From v1.0.10 to permit disable/enable StaticIP configuration in Config Portal from sketch. Valid only if DHCP is used.
// You'll loose the feature of dynamically changing from DHCP to static IP, or vice versa
// You have to explicitly specify false to disable the feature.
//#define USE_STATIC_IP_CONFIG_IN_CP false
// Use false to disable NTP config. Advisable when using Cellphone, Tablet to access Config Portal.
// See Issue 23: On Android phone ConfigPortal is unresponsive (https://github.com/khoih-prog/ESP_WiFiManager/issues/23)
#define USE_ESP_WIFIMANAGER_NTP false
// Use true to enable CloudFlare NTP service. System can hang if you don't have Internet access while accessing CloudFlare
// See Issue #21: CloudFlare link in the default portal (https://github.com/khoih-prog/ESP_WiFiManager/issues/21)
#define USE_CLOUDFLARE_NTP false
// New in v1.0.11
#define USING_CORS_FEATURE true
//////
// Use USE_DHCP_IP == true for dynamic DHCP IP, false to use static IP which you have to change accordingly to your network
#if (defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP)
// Force DHCP to be true
#if defined(USE_DHCP_IP)
#undef USE_DHCP_IP
#endif
#define USE_DHCP_IP true
#else
// You can select DHCP or Static IP here
//#define USE_DHCP_IP true
#define USE_DHCP_IP false
#endif
// Use USE_DHCP_IP == true for dynamic DHCP IP, false to use static IP which you have to change accordingly to your network
#if (defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP)
// Force DHCP to be true
#if defined(USE_DHCP_IP)
#undef USE_DHCP_IP
#endif
#define USE_DHCP_IP true
#else
// You can select DHCP or Static IP here
//#define USE_DHCP_IP true
#define USE_DHCP_IP false
#endif
#if ( USE_DHCP_IP || ( defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP ) )
// Use DHCP
#warning Using DHCP IP
IPAddress stationIP = IPAddress(0, 0, 0, 0);
IPAddress gatewayIP = IPAddress(192, 168, 2, 1);
IPAddress netMask = IPAddress(255, 255, 255, 0);
#else
// Use static IP
#warning Using static IP
#ifdef ESP32
IPAddress stationIP = IPAddress(192, 168, 2, 232);
#else
IPAddress stationIP = IPAddress(192, 168, 2, 186);
#endif
IPAddress gatewayIP = IPAddress(192, 168, 2, 1);
IPAddress netMask = IPAddress(255, 255, 255, 0);
#endif
#define USE_CONFIGURABLE_DNS true
IPAddress dns1IP = gatewayIP;
IPAddress dns2IP = IPAddress(8, 8, 8, 8);
#include <ESP_WiFiManager.h> //https://github.com/khoih-prog/ESP_WiFiManager
const char* host = "esp32-fs-browser";
#define HTTP_PORT 80
WebServer server(HTTP_PORT);
//holds the current upload
File fsUploadFile;
// Function Prototypes
uint8_t connectMultiWiFi(void);
void heartBeatPrint(void)
{
static int num = 1;
if (WiFi.status() == WL_CONNECTED)
Serial.print("H"); // H means connected to WiFi
else
Serial.print("F"); // F means not connected to WiFi
if (num == 80)
{
Serial.println();
num = 1;
}
else if (num++ % 10 == 0)
{
Serial.print(" ");
}
}
void check_WiFi(void)
{
if ( (WiFi.status() != WL_CONNECTED) )
{
Serial.println("\nWiFi lost. Call connectMultiWiFi in loop");
connectMultiWiFi();
}
}
void check_status(void)
{
static ulong checkstatus_timeout = 0;
static ulong checkwifi_timeout = 0;
static ulong current_millis;
#define WIFICHECK_INTERVAL 1000L
#define HEARTBEAT_INTERVAL 10000L
current_millis = millis();
// Check WiFi every WIFICHECK_INTERVAL (1) seconds.
if ((current_millis > checkwifi_timeout) || (checkwifi_timeout == 0))
{
check_WiFi();
checkwifi_timeout = current_millis + WIFICHECK_INTERVAL;
}
// Print hearbeat every HEARTBEAT_INTERVAL (10) seconds.
if ((current_millis > checkstatus_timeout) || (checkstatus_timeout == 0))
{
heartBeatPrint();
checkstatus_timeout = current_millis + HEARTBEAT_INTERVAL;
}
}
//format bytes
String formatBytes(size_t bytes)
{
if (bytes < 1024)
{
return String(bytes) + "B";
}
else if (bytes < (1024 * 1024))
{
return String(bytes / 1024.0) + "KB";
}
else if (bytes < (1024 * 1024 * 1024))
{
return String(bytes / 1024.0 / 1024.0) + "MB";
}
else
{
return String(bytes / 1024.0 / 1024.0 / 1024.0) + "GB";
}
}
String getContentType(String filename)
{
if (server.hasArg("download"))
{
return "application/octet-stream";
}
else if (filename.endsWith(".htm"))
{
return "text/html";
}
else if (filename.endsWith(".html"))
{
return "text/html";
}
else if (filename.endsWith(".css"))
{
return "text/css";
}
else if (filename.endsWith(".js"))
{
return "application/javascript";
}
else if (filename.endsWith(".png"))
{
return "image/png";
}
else if (filename.endsWith(".gif"))
{
return "image/gif";
}
else if (filename.endsWith(".jpg"))
{
return "image/jpeg";
}
else if (filename.endsWith(".ico"))
{
return "image/x-icon";
}
else if (filename.endsWith(".xml"))
{
return "text/xml";
}
else if (filename.endsWith(".pdf"))
{
return "application/x-pdf";
}
else if (filename.endsWith(".zip"))
{
return "application/x-zip";
}
else if (filename.endsWith(".gz"))
{
return "application/x-gzip";
}
return "text/plain";
}
bool handleFileRead(String path)
{
DBG_OUTPUT_PORT.println("handleFileRead: " + path);
if (path.endsWith("/"))
{
path += "index.htm";
}
String contentType = getContentType(path);
String pathWithGz = path + ".gz";
if (filesystem->exists(pathWithGz) || filesystem->exists(path))
{
if (filesystem->exists(pathWithGz))
{
path += ".gz";
}
File file = filesystem->open(path, "r");
server.streamFile(file, contentType);
file.close();
return true;
}
return false;
}
void handleFileUpload()
{
if (server.uri() != "/edit")
{
return;
}
HTTPUpload& upload = server.upload();
if (upload.status == UPLOAD_FILE_START)
{
String filename = upload.filename;
if (!filename.startsWith("/"))
{
filename = "/" + filename;
}
DBG_OUTPUT_PORT.print("handleFileUpload Name: "); DBG_OUTPUT_PORT.println(filename);
fsUploadFile = filesystem->open(filename, "w");
filename.clear();
}
else if (upload.status == UPLOAD_FILE_WRITE)
{
//DBG_OUTPUT_PORT.print("handleFileUpload Data: "); DBG_OUTPUT_PORT.println(upload.currentSize);
if (fsUploadFile)
{
fsUploadFile.write(upload.buf, upload.currentSize);
}
}
else if (upload.status == UPLOAD_FILE_END)
{
if (fsUploadFile)
{
fsUploadFile.close();
}
DBG_OUTPUT_PORT.print("handleFileUpload Size: "); DBG_OUTPUT_PORT.println(upload.totalSize);
}
}
void handleFileDelete()
{
if (server.args() == 0)
{
return server.send(500, "text/plain", "BAD ARGS");
}
String path = server.arg(0);
DBG_OUTPUT_PORT.println("handleFileDelete: " + path);
if (path == "/")
{
return server.send(500, "text/plain", "BAD PATH");
}
if (!filesystem->exists(path))
{
return server.send(404, "text/plain", "FileNotFound");
}
filesystem->remove(path);
server.send(200, "text/plain", "");
path.clear();
}
void handleFileCreate()
{
if (server.args() == 0)
{
return server.send(500, "text/plain", "BAD ARGS");
}
String path = server.arg(0);
DBG_OUTPUT_PORT.println("handleFileCreate: " + path);
if (path == "/")
{
return server.send(500, "text/plain", "BAD PATH");
}
if (filesystem->exists(path))
{
return server.send(500, "text/plain", "FILE EXISTS");
}
File file = filesystem->open(path, "w");
if (file)
{
file.close();
}
else
{
return server.send(500, "text/plain", "CREATE FAILED");
}
server.send(200, "text/plain", "");
path.clear();
}
void handleFileList()
{
if (!server.hasArg("dir"))
{
server.send(500, "text/plain", "BAD ARGS");
return;
}
String path = server.arg("dir");
DBG_OUTPUT_PORT.println("handleFileList: " + path);
File root = FileFS.open(path);
path = String();
String output = "[";
if (root.isDirectory())
{
File file = root.openNextFile();
while (file)
{
if (output != "[")
{
output += ',';
}
output += "{\"type\":\"";
output += (file.isDirectory()) ? "dir" : "file";
output += "\",\"name\":\"";
output += String(file.name()).substring(1);
output += "\"}";
file = root.openNextFile();
}
}
output += "]";
DBG_OUTPUT_PORT.println("handleFileList: " + output);
server.send(200, "text/json", output);
}
void loadConfigData(void)
{
File file = FileFS.open(CONFIG_FILENAME, "r");
LOGERROR(F("LoadWiFiCfgFile "));
if (file)
{
file.readBytes((char *) &WM_config, sizeof(WM_config));
file.close();
LOGERROR(F("OK"));
}
else
{
LOGERROR(F("failed"));
}
}
void saveConfigData(void)
{
File file = FileFS.open(CONFIG_FILENAME, "w");
LOGERROR(F("SaveWiFiCfgFile "));
if (file)
{
file.write((uint8_t*) &WM_config, sizeof(WM_config));
file.close();
LOGERROR(F("OK"));
}
else
{
LOGERROR(F("failed"));
}
}
uint8_t connectMultiWiFi(void)
{
#if ESP32
// For ESP32, this better be 0 to shorten the connect time
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 0
#else
// For ESP8266, this better be 2200 to enable connect the 1st time
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 2200L
#endif
#define WIFI_MULTI_CONNECT_WAITING_MS 100L
uint8_t status;
LOGERROR(F("ConnectMultiWiFi with :"));
if ( (Router_SSID != "") && (Router_Pass != "") )
{
LOGERROR3(F("* Flash-stored Router_SSID = "), Router_SSID, F(", Router_Pass = "), Router_Pass );
}
for (uint8_t i = 0; i < NUM_WIFI_CREDENTIALS; i++)
{
// Don't permit NULL SSID and password len < MIN_AP_PASSWORD_SIZE (8)
if ( (String(WM_config.WiFi_Creds[i].wifi_ssid) != "") && (strlen(WM_config.WiFi_Creds[i].wifi_pw) >= MIN_AP_PASSWORD_SIZE) )
{
LOGERROR3(F("* Additional SSID = "), WM_config.WiFi_Creds[i].wifi_ssid, F(", PW = "), WM_config.WiFi_Creds[i].wifi_pw );
}
}
LOGERROR(F("Connecting MultiWifi..."));
WiFi.mode(WIFI_STA);
#if !USE_DHCP_IP
#if USE_CONFIGURABLE_DNS
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
WiFi.config(stationIP, gatewayIP, netMask, dns1IP, dns2IP);
#else
// Set static IP, Gateway, Subnetmask, Use auto DNS1 and DNS2.
WiFi.config(stationIP, gatewayIP, netMask);
#endif
#endif
int i = 0;
status = wifiMulti.run();
delay(WIFI_MULTI_1ST_CONNECT_WAITING_MS);
while ( ( i++ < 10 ) && ( status != WL_CONNECTED ) )
{
status = wifiMulti.run();
if ( status == WL_CONNECTED )
break;
else
delay(WIFI_MULTI_CONNECT_WAITING_MS);
}
if ( status == WL_CONNECTED )
{
LOGERROR1(F("WiFi connected after time: "), i);
LOGERROR3(F("SSID:"), WiFi.SSID(), F(",RSSI="), WiFi.RSSI());
LOGERROR3(F("Channel:"), WiFi.channel(), F(",IP address:"), WiFi.localIP() );
}
else
LOGERROR(F("WiFi not connected"));
return status;
}
void setup(void)
{
DBG_OUTPUT_PORT.begin(115200);
while (!DBG_OUTPUT_PORT);
DBG_OUTPUT_PORT.print("\nStarting ESP32_FSWebServer with DoubleResetDetect using " + String(FS_Name));
DBG_OUTPUT_PORT.println(" on " + String(ARDUINO_BOARD));
DBG_OUTPUT_PORT.setDebugOutput(false);
if (FORMAT_FILESYSTEM)
FileFS.format();
// Format SPIFFS if not yet
if (!FileFS.begin(true))
{
DBG_OUTPUT_PORT.print(FS_Name);
DBG_OUTPUT_PORT.println(F(" failed! AutoFormatting."));
}
File root = FileFS.open("/");
File file = root.openNextFile();
while (file)
{
String fileName = file.name();
size_t fileSize = file.size();
DBG_OUTPUT_PORT.printf("FS File: %s, size: %s\n", fileName.c_str(), formatBytes(fileSize).c_str());
file = root.openNextFile();
}
DBG_OUTPUT_PORT.println();
unsigned long startedAt = millis();
//Local intialization. Once its business is done, there is no need to keep it around
// Use this to default DHCP hostname to ESP8266-XXXXXX or ESP32-XXXXXX
//ESP_WiFiManager ESP_wifiManager;
// Use this to personalize DHCP hostname (RFC952 conformed)
ESP_WiFiManager ESP_wifiManager("ESP32-FSWebServer");
//set custom ip for portal
ESP_wifiManager.setAPStaticIPConfig(IPAddress(192, 168, 100, 1), IPAddress(192, 168, 100, 1), IPAddress(255, 255, 255, 0));
ESP_wifiManager.setMinimumSignalQuality(-1);
// From v1.0.10 only
// Set config portal channel, default = 1. Use 0 => random channel from 1-13
ESP_wifiManager.setConfigPortalChannel(0);
//////
#if !USE_DHCP_IP
#if USE_CONFIGURABLE_DNS
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
ESP_wifiManager.setSTAStaticIPConfig(stationIP, gatewayIP, netMask, dns1IP, dns2IP);
#else
// Set static IP, Gateway, Subnetmask, Use auto DNS1 and DNS2.
ESP_wifiManager.setSTAStaticIPConfig(stationIP, gatewayIP, netMask);
#endif
#endif
// New from v1.1.1
#if USING_CORS_FEATURE
ESP_wifiManager.setCORSHeader("Your Access-Control-Allow-Origin");
#endif
// We can't use WiFi.SSID() in ESP32as it's only valid after connected.
// SSID and Password stored in ESP32 wifi_ap_record_t and wifi_config_t are also cleared in reboot
// Have to create a new function to store in EEPROM/SPIFFS for this purpose
Router_SSID = ESP_wifiManager.WiFi_SSID();
Router_Pass = ESP_wifiManager.WiFi_Pass();
//Remove this line if you do not want to see WiFi password printed
DBG_OUTPUT_PORT.println("Stored: SSID = " + Router_SSID + ", Pass = " + Router_Pass);
// SSID to uppercase
ssid.toUpperCase();
// From v1.1.0, Don't permit NULL password
if ( (Router_SSID == "") || (Router_Pass == "") )
{
DBG_OUTPUT_PORT.println("We haven't got any access point credentials, so get them now");
initialConfig = true;
// Starts an access point
if (!ESP_wifiManager.startConfigPortal((const char *) ssid.c_str(), password))
DBG_OUTPUT_PORT.println("Not connected to WiFi but continuing anyway.");
else
DBG_OUTPUT_PORT.println("WiFi connected...yeey :)");
// Stored for later usage, from v1.1.0, but clear first
memset(&WM_config, 0, sizeof(WM_config));
for (uint8_t i = 0; i < NUM_WIFI_CREDENTIALS; i++)
{
String tempSSID = ESP_wifiManager.getSSID(i);
String tempPW = ESP_wifiManager.getPW(i);
if (strlen(tempSSID.c_str()) < sizeof(WM_config.WiFi_Creds[i].wifi_ssid) - 1)
strcpy(WM_config.WiFi_Creds[i].wifi_ssid, tempSSID.c_str());
else
strncpy(WM_config.WiFi_Creds[i].wifi_ssid, tempSSID.c_str(), sizeof(WM_config.WiFi_Creds[i].wifi_ssid) - 1);
if (strlen(tempPW.c_str()) < sizeof(WM_config.WiFi_Creds[i].wifi_pw) - 1)
strcpy(WM_config.WiFi_Creds[i].wifi_pw, tempPW.c_str());
else
strncpy(WM_config.WiFi_Creds[i].wifi_pw, tempPW.c_str(), sizeof(WM_config.WiFi_Creds[i].wifi_pw) - 1);
// Don't permit NULL SSID and password len < MIN_AP_PASSWORD_SIZE (8)
if ( (String(WM_config.WiFi_Creds[i].wifi_ssid) != "") && (strlen(WM_config.WiFi_Creds[i].wifi_pw) >= MIN_AP_PASSWORD_SIZE) )
{
LOGERROR3(F("* Add SSID = "), WM_config.WiFi_Creds[i].wifi_ssid, F(", PW = "), WM_config.WiFi_Creds[i].wifi_pw );
wifiMulti.addAP(WM_config.WiFi_Creds[i].wifi_ssid, WM_config.WiFi_Creds[i].wifi_pw);
}
}
saveConfigData();
}
else
{
wifiMulti.addAP(Router_SSID.c_str(), Router_Pass.c_str());
}
startedAt = millis();
if (!initialConfig)
{
// Load stored data, the addAP ready for MultiWiFi reconnection
loadConfigData();
for (uint8_t i = 0; i < NUM_WIFI_CREDENTIALS; i++)
{
// Don't permit NULL SSID and password len < MIN_AP_PASSWORD_SIZE (8)
if ( (String(WM_config.WiFi_Creds[i].wifi_ssid) != "") && (strlen(WM_config.WiFi_Creds[i].wifi_pw) >= MIN_AP_PASSWORD_SIZE) )
{
LOGERROR3(F("* Add SSID = "), WM_config.WiFi_Creds[i].wifi_ssid, F(", PW = "), WM_config.WiFi_Creds[i].wifi_pw );
wifiMulti.addAP(WM_config.WiFi_Creds[i].wifi_ssid, WM_config.WiFi_Creds[i].wifi_pw);
}
}
if ( WiFi.status() != WL_CONNECTED )
{
DBG_OUTPUT_PORT.println("ConnectMultiWiFi in setup");
connectMultiWiFi();
}
}
DBG_OUTPUT_PORT.print("After waiting ");
DBG_OUTPUT_PORT.print((float) (millis() - startedAt) / 1000L);
DBG_OUTPUT_PORT.print(" secs more in setup(), connection result is ");
if (WiFi.status() == WL_CONNECTED)
{
DBG_OUTPUT_PORT.print("connected. Local IP: ");
DBG_OUTPUT_PORT.println(WiFi.localIP());
}
else
DBG_OUTPUT_PORT.println(ESP_wifiManager.getStatus(WiFi.status()));
//SERVER INIT
//list directory
server.on("/list", HTTP_GET, handleFileList);
//load editor
server.on("/edit", HTTP_GET, []()
{
if (!handleFileRead("/edit.htm"))
{
server.send(404, "text/plain", "FileNotFound");
}
});
//create file
server.on("/edit", HTTP_PUT, handleFileCreate);
//delete file
server.on("/edit", HTTP_DELETE, handleFileDelete);
//first callback is called after the request has ended with all parsed arguments
//second callback handles file uploads at that location
server.on("/edit", HTTP_POST, []()
{
server.send(200, "text/plain", "");
}, handleFileUpload);
//called when the url is not defined here
//use it to load content from SPIFFS
server.onNotFound([]()
{
if (!handleFileRead(server.uri()))
{
server.send(404, "text/plain", "FileNotFound");
}
});
//get heap status, analog input value and all GPIO statuses in one json call
server.on("/all", HTTP_GET, []()
{
String json = "{";
json += "\"heap\":" + String(ESP.getFreeHeap());
json += ", \"analog\":" + String(analogRead(A0));
json += ", \"gpio\":" + String((uint32_t)(0));
json += "}";
server.send(200, "text/json", json);
json = String();
});
server.begin();
DBG_OUTPUT_PORT.print("HTTP server started @ ");
DBG_OUTPUT_PORT.println(WiFi.localIP());
MDNS.begin(host);
// Add service to MDNS-SD
MDNS.addService("http", "tcp", HTTP_PORT);
DBG_OUTPUT_PORT.print("Open http://");
DBG_OUTPUT_PORT.print(host);
DBG_OUTPUT_PORT.println(".local/edit to see the file browser");
}
void loop(void)
{
server.handleClient();
// this is just for checking if we are alive and connected to WiFi
check_status();
}