// From v1.1.0
//////
// You only need to format the filesystem once
//#define FORMAT_FILESYSTEM true
#define FORMAT_FILESYSTEM false
// LittleFS has higher priority than SPIFFS
#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 2) )
#define USE_LITTLEFS true
#define USE_SPIFFS false
#elif defined(ARDUINO_ESP32C3_DEV)
// For core v1.0.6-, ESP32-C3 only supporting SPIFFS and EEPROM. To use v2.0.0+ for LittleFS
#define USE_LITTLEFS false
#define USE_SPIFFS true
#endif
#if USE_LITTLEFS
// Use LittleFS
#include "FS.h"
// Check cores/esp32/esp_arduino_version.h and cores/esp32/core_version.h
//#if ( ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(2, 0, 0) ) //(ESP_ARDUINO_VERSION_MAJOR >= 2)
#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 2) )
#if (_ESPASYNC_WIFIMGR_LOGLEVEL_ > 3)
#warning Using ESP32 Core 1.0.6 or 2.0.0+
#endif
// The library has been merged into esp32 core from release 1.0.6
#include // https://github.com/espressif/arduino-esp32/tree/master/libraries/LittleFS
FS* filesystem = &LittleFS;
#define FileFS LittleFS
#define FS_Name "LittleFS"
#else
#if (_ESPASYNC_WIFIMGR_LOGLEVEL_ > 3)
#warning Using ESP32 Core 1.0.5-. You must install LITTLEFS library
#endif
// The library has been merged into esp32 core from release 1.0.6
#include // https://github.com/lorol/LITTLEFS
FS* filesystem = &LITTLEFS;
#define FileFS LITTLEFS
#define FS_Name "LittleFS"
#endif
#elif USE_SPIFFS
#include
FS* filesystem = &SPIFFS;
#define FileFS SPIFFS
#define FS_Name "SPIFFS"
#else
// Use FFat
#include
FS* filesystem = &FFat;
#define FileFS FFat
#define FS_Name "FFat"
#endif
#define LED_BUILTIN 2
#define LED_ON HIGH
#define LED_OFF LOW
#include
// These defines must be put before #include
// to select where to store DoubleResetDetector's variable.
// For ESP32, You must select one to be true (EEPROM or SPIFFS)
// Otherwise, library will use default EEPROM storage
#if USE_LITTLEFS
#define ESP_DRD_USE_LITTLEFS true
#define ESP_DRD_USE_SPIFFS false
#define ESP_DRD_USE_EEPROM false
#elif USE_SPIFFS
#define ESP_DRD_USE_LITTLEFS false
#define ESP_DRD_USE_SPIFFS true
#define ESP_DRD_USE_EEPROM false
#else
#define ESP_DRD_USE_LITTLEFS false
#define ESP_DRD_USE_SPIFFS false
#define ESP_DRD_USE_EEPROM true
#endif
#define DOUBLERESETDETECTOR_DEBUG true //false
#include //https://github.com/khoih-prog/ESP_DoubleResetDetector
// Number of seconds after reset during which a
// subseqent reset will be considered a double reset.
#define DRD_TIMEOUT 10
// RTC Memory Address for the DoubleResetDetector to use
#define DRD_ADDRESS 0
//DoubleResetDetector drd(DRD_TIMEOUT, DRD_ADDRESS);
DoubleResetDetector* drd = NULL;
//////
// 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
// Assuming max 49 chars
#define TZNAME_MAX_LEN 50
#define TIMEZONE_MAX_LEN 50
typedef struct
{
WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS];
char TZ_Name[TZNAME_MAX_LEN]; // "America/Toronto"
char TZ[TIMEZONE_MAX_LEN]; // "EST5EDT,M3.2.0,M11.1.0"
uint16_t checksum;
} 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
#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
// Just use enough to save memory. On ESP8266, can cause blank ConfigPortal screen
// if using too much memory
#define USING_AFRICA false
#define USING_AMERICA true
#define USING_ANTARCTICA false
#define USING_ASIA false
#define USING_ATLANTIC false
#define USING_AUSTRALIA false
#define USING_EUROPE false
#define USING_INDIAN false
#define USING_PACIFIC false
#define USING_ETC_GMT 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
#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
#if ( USE_DHCP_IP )
// Use DHCP
#if (_ESPASYNC_WIFIMGR_LOGLEVEL_ > 3)
#warning Using DHCP IP
#endif
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
#if (_ESPASYNC_WIFIMGR_LOGLEVEL_ > 3)
#warning Using static IP
#endif
#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);
#define USE_CUSTOM_AP_IP false
IPAddress APStaticIP = IPAddress(192, 168, 100, 1);
IPAddress APStaticGW = IPAddress(192, 168, 100, 1);
IPAddress APStaticSN = IPAddress(255, 255, 255, 0);
#include //https://github.com/khoih-prog/ESPAsync_WiFiManager
// Redundant, for v1.10.0 only
//#include //https://github.com/khoih-prog/ESPAsync_WiFiManager
// SSID and PW for Config Portal
String ssid = "ESP_" + String(ESP_getChipId(), HEX);
String password;
// SSID and PW for your Router
String Router_SSID;
String Router_Pass;
String host = "async-esp32fs";
#define HTTP_PORT 80
AsyncWebServer server(HTTP_PORT);
AsyncDNSServer dnsServer;
AsyncEventSource events("/events");
String http_username = "admin";
String http_password = "admin";
String separatorLine = "===============================================================";
///////////////////////////////////////////
// New in v1.4.0
/******************************************
* // Defined in ESPAsync_WiFiManager.h
typedef struct
{
IPAddress _ap_static_ip;
IPAddress _ap_static_gw;
IPAddress _ap_static_sn;
} WiFi_AP_IPConfig;
typedef struct
{
IPAddress _sta_static_ip;
IPAddress _sta_static_gw;
IPAddress _sta_static_sn;
#if USE_CONFIGURABLE_DNS
IPAddress _sta_static_dns1;
IPAddress _sta_static_dns2;
#endif
} WiFi_STA_IPConfig;
******************************************/
WiFi_AP_IPConfig WM_AP_IPconfig;
WiFi_STA_IPConfig WM_STA_IPconfig;
void initAPIPConfigStruct(WiFi_AP_IPConfig &in_WM_AP_IPconfig)
{
in_WM_AP_IPconfig._ap_static_ip = APStaticIP;
in_WM_AP_IPconfig._ap_static_gw = APStaticGW;
in_WM_AP_IPconfig._ap_static_sn = APStaticSN;
}
void initSTAIPConfigStruct(WiFi_STA_IPConfig &in_WM_STA_IPconfig)
{
in_WM_STA_IPconfig._sta_static_ip = stationIP;
in_WM_STA_IPconfig._sta_static_gw = gatewayIP;
in_WM_STA_IPconfig._sta_static_sn = netMask;
#if USE_CONFIGURABLE_DNS
in_WM_STA_IPconfig._sta_static_dns1 = dns1IP;
in_WM_STA_IPconfig._sta_static_dns2 = dns2IP;
#endif
}
void displayIPConfigStruct(WiFi_STA_IPConfig in_WM_STA_IPconfig)
{
LOGERROR3(F("stationIP ="), in_WM_STA_IPconfig._sta_static_ip, F(", gatewayIP ="), in_WM_STA_IPconfig._sta_static_gw);
LOGERROR1(F("netMask ="), in_WM_STA_IPconfig._sta_static_sn);
#if USE_CONFIGURABLE_DNS
LOGERROR3(F("dns1IP ="), in_WM_STA_IPconfig._sta_static_dns1, F(", dns2IP ="), in_WM_STA_IPconfig._sta_static_dns2);
#endif
}
void configWiFi(WiFi_STA_IPConfig in_WM_STA_IPconfig)
{
#if USE_CONFIGURABLE_DNS
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
WiFi.config(in_WM_STA_IPconfig._sta_static_ip, in_WM_STA_IPconfig._sta_static_gw, in_WM_STA_IPconfig._sta_static_sn, in_WM_STA_IPconfig._sta_static_dns1, in_WM_STA_IPconfig._sta_static_dns2);
#else
// Set static IP, Gateway, Subnetmask, Use auto DNS1 and DNS2.
WiFi.config(in_WM_STA_IPconfig._sta_static_ip, in_WM_STA_IPconfig._sta_static_gw, in_WM_STA_IPconfig._sta_static_sn);
#endif
}
///////////////////////////////////////////
uint8_t connectMultiWiFi()
{
#if ESP32
// For ESP32, this better be 0 to shorten the connect time.
// For ESP32-S2/C3, must be > 500
#if ( USING_ESP32_S2 || USING_ESP32_C3 )
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 500L
#else
// For ESP32 core v1.0.6, must be >= 500
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 800L
#endif
#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 500L
uint8_t status;
//WiFi.mode(WIFI_STA);
LOGERROR(F("ConnectMultiWiFi with :"));
if ( (Router_SSID != "") && (Router_Pass != "") )
{
LOGERROR3(F("* Flash-stored Router_SSID = "), Router_SSID, F(", Router_Pass = "), Router_Pass );
LOGERROR3(F("* Add SSID = "), Router_SSID, F(", PW = "), Router_Pass );
wifiMulti.addAP(Router_SSID.c_str(), Router_Pass.c_str());
}
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
// New in v1.4.0
configWiFi(WM_STA_IPconfig);
//////
#endif
int i = 0;
status = wifiMulti.run();
delay(WIFI_MULTI_1ST_CONNECT_WAITING_MS);
while ( ( i++ < 20 ) && ( status != WL_CONNECTED ) )
{
status = WiFi.status();
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"));
// To avoid unnecessary DRD
drd->loop();
ESP.restart();
}
return status;
}
//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";
}
}
void toggleLED()
{
//toggle state
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
#if USE_ESP_WIFIMANAGER_NTP
void printLocalTime()
{
#if ESP8266
static time_t now;
now = time(nullptr);
if ( now > 1451602800 )
{
Serial.print("Local Date/Time: ");
Serial.print(ctime(&now));
}
#else
struct tm timeinfo;
getLocalTime( &timeinfo );
// Valid only if year > 2000.
// You can get from timeinfo : tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec
if (timeinfo.tm_year > 100 )
{
Serial.print("Local Date/Time: ");
Serial.print( asctime( &timeinfo ) );
}
#endif
}
#endif
void heartBeatPrint()
{
#if USE_ESP_WIFIMANAGER_NTP
printLocalTime();
#else
static int num = 1;
if (WiFi.status() == WL_CONNECTED)
Serial.print(F("H")); // H means connected to WiFi
else
Serial.print(F("F")); // F means not connected to WiFi
if (num == 80)
{
Serial.println();
num = 1;
}
else if (num++ % 10 == 0)
{
Serial.print(F(" "));
}
#endif
}
void check_WiFi()
{
if ( (WiFi.status() != WL_CONNECTED) )
{
Serial.println(F("\nWiFi lost. Call connectMultiWiFi in loop"));
connectMultiWiFi();
}
}
void check_status()
{
static ulong checkstatus_timeout = 0;
static ulong LEDstatus_timeout = 0;
static ulong checkwifi_timeout = 0;
static ulong current_millis;
#define WIFICHECK_INTERVAL 1000L
#if USE_ESP_WIFIMANAGER_NTP
#define HEARTBEAT_INTERVAL 60000L
#else
#define HEARTBEAT_INTERVAL 10000L
#endif
#define LED_INTERVAL 2000L
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;
}
if ((current_millis > LEDstatus_timeout) || (LEDstatus_timeout == 0))
{
// Toggle LED at LED_INTERVAL = 2s
toggleLED();
LEDstatus_timeout = current_millis + LED_INTERVAL;
}
// Print hearbeat every HEARTBEAT_INTERVAL (10) seconds.
if ((current_millis > checkstatus_timeout) || (checkstatus_timeout == 0))
{
heartBeatPrint();
checkstatus_timeout = current_millis + HEARTBEAT_INTERVAL;
}
}
int calcChecksum(uint8_t* address, uint16_t sizeToCalc)
{
uint16_t checkSum = 0;
for (uint16_t index = 0; index < sizeToCalc; index++)
{
checkSum += * ( ( (byte*) address ) + index);
}
return checkSum;
}
bool loadConfigData()
{
File file = FileFS.open(CONFIG_FILENAME, "r");
LOGERROR(F("LoadWiFiCfgFile "));
memset((void *) &WM_config, 0, sizeof(WM_config));
// New in v1.4.0
memset((void *) &WM_STA_IPconfig, 0, sizeof(WM_STA_IPconfig));
//////
if (file)
{
file.readBytes((char *) &WM_config, sizeof(WM_config));
// New in v1.4.0
file.readBytes((char *) &WM_STA_IPconfig, sizeof(WM_STA_IPconfig));
//////
file.close();
LOGERROR(F("OK"));
if ( WM_config.checksum != calcChecksum( (uint8_t*) &WM_config, sizeof(WM_config) - sizeof(WM_config.checksum) ) )
{
LOGERROR(F("WM_config checksum wrong"));
return false;
}
// New in v1.4.0
displayIPConfigStruct(WM_STA_IPconfig);
//////
return true;
}
else
{
LOGERROR(F("failed"));
return false;
}
}
void saveConfigData()
{
File file = FileFS.open(CONFIG_FILENAME, "w");
LOGERROR(F("SaveWiFiCfgFile "));
if (file)
{
WM_config.checksum = calcChecksum( (uint8_t*) &WM_config, sizeof(WM_config) - sizeof(WM_config.checksum) );
file.write((uint8_t*) &WM_config, sizeof(WM_config));
displayIPConfigStruct(WM_STA_IPconfig);
// New in v1.4.0
file.write((uint8_t*) &WM_STA_IPconfig, sizeof(WM_STA_IPconfig));
//////
file.close();
LOGERROR(F("OK"));
}
else
{
LOGERROR(F("failed"));
}
}
void setup()
{
//set led pin as output
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
while (!Serial);
delay(200);
Serial.print(F("\nStarting Async_ESP32_FSWebServer_DRD using ")); Serial.print(FS_Name);
Serial.print(F(" on ")); Serial.println(ARDUINO_BOARD);
Serial.println(ESP_ASYNC_WIFIMANAGER_VERSION);
Serial.println(ESP_DOUBLE_RESET_DETECTOR_VERSION);
#if defined(ESP_ASYNC_WIFIMANAGER_VERSION_INT)
if (ESP_ASYNC_WIFIMANAGER_VERSION_INT < ESP_ASYNC_WIFIMANAGER_VERSION_MIN)
{
Serial.print("Warning. Must use this example on Version later than : ");
Serial.println(ESP_ASYNC_WIFIMANAGER_VERSION_MIN_TARGET);
}
#endif
Serial.setDebugOutput(false);
if (FORMAT_FILESYSTEM)
FileFS.format();
// Format FileFS if not yet
if (!FileFS.begin(true))
{
Serial.println(F("SPIFFS/LittleFS failed! Already tried formatting."));
if (!FileFS.begin())
{
// prevents debug info from the library to hide err message.
delay(100);
#if USE_LITTLEFS
Serial.println(F("LittleFS failed!. Please use SPIFFS or EEPROM. Stay forever"));
#else
Serial.println(F("SPIFFS failed!. Please use LittleFS or EEPROM. Stay forever"));
#endif
while (true)
{
delay(1);
}
}
}
File root = FileFS.open("/");
File file = root.openNextFile();
while (file)
{
String fileName = file.name();
size_t fileSize = file.size();
Serial.printf("FS File: %s, size: %s\n", fileName.c_str(), formatBytes(fileSize).c_str());
file = root.openNextFile();
}
Serial.println();
drd = new DoubleResetDetector(DRD_TIMEOUT, DRD_ADDRESS);
if (!drd)
Serial.println(F("Can't instantiate. Disable DRD feature"));
unsigned long startedAt = millis();
// New in v1.4.0
initAPIPConfigStruct(WM_AP_IPconfig);
initSTAIPConfigStruct(WM_STA_IPconfig);
//////
digitalWrite(LED_BUILTIN, LED_ON);
//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
//ESPAsync_WiFiManager ESPAsync_wifiManager(&webServer, &dnsServer);
// Use this to personalize DHCP hostname (RFC952 conformed)0
#if ( USING_ESP32_S2 || USING_ESP32_C3 )
ESPAsync_WiFiManager ESPAsync_wifiManager(&server, NULL, "AsyncESP32-FSWebServer");
#else
AsyncDNSServer dnsServer;
ESPAsync_WiFiManager ESPAsync_wifiManager(&server, &dnsServer, "AsyncESP32-FSWebServer");
#endif
#if USE_CUSTOM_AP_IP
//set custom ip for portal
// New in v1.4.0
ESPAsync_wifiManager.setAPStaticIPConfig(WM_AP_IPconfig);
//////
#endif
ESPAsync_wifiManager.setMinimumSignalQuality(-1);
// Set config portal channel, default = 1. Use 0 => random channel from 1-13
ESPAsync_wifiManager.setConfigPortalChannel(0);
//////
#if !USE_DHCP_IP
// Set (static IP, Gateway, Subnetmask, DNS1 and DNS2) or (IP, Gateway, Subnetmask). New in v1.0.5
// New in v1.4.0
ESPAsync_wifiManager.setSTAStaticIPConfig(WM_STA_IPconfig);
//////
#endif
// New from v1.1.1
#if USING_CORS_FEATURE
ESPAsync_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 = ESPAsync_wifiManager.WiFi_SSID();
Router_Pass = ESPAsync_wifiManager.WiFi_Pass();
//Remove this line if you do not want to see WiFi password printed
Serial.println("ESP Self-Stored: SSID = " + Router_SSID + ", Pass = " + Router_Pass);
// SSID to uppercase
ssid.toUpperCase();
password = "My" + ssid;
bool configDataLoaded = false;
// From v1.1.0, Don't permit NULL password
if ( (Router_SSID != "") && (Router_Pass != "") )
{
LOGERROR3(F("* Add SSID = "), Router_SSID, F(", PW = "), Router_Pass);
wifiMulti.addAP(Router_SSID.c_str(), Router_Pass.c_str());
ESPAsync_wifiManager.setConfigPortalTimeout(120); //If no access point name has been previously entered disable timeout.
Serial.println(F("Got ESP Self-Stored Credentials. Timeout 120s for Config Portal"));
}
if (loadConfigData())
{
configDataLoaded = true;
ESPAsync_wifiManager.setConfigPortalTimeout(120); //If no access point name has been previously entered disable timeout.
Serial.println(F("Got stored Credentials. Timeout 120s for Config Portal"));
#if USE_ESP_WIFIMANAGER_NTP
if ( strlen(WM_config.TZ_Name) > 0 )
{
LOGERROR3(F("Saving current TZ_Name ="), WM_config.TZ_Name, F(", TZ = "), WM_config.TZ);
#if ESP8266
configTime(WM_config.TZ, "pool.ntp.org");
#else
//configTzTime(WM_config.TZ, "pool.ntp.org" );
configTzTime(WM_config.TZ, "time.nist.gov", "0.pool.ntp.org", "1.pool.ntp.org");
#endif
}
else
{
Serial.println(F("Current Timezone is not set. Enter Config Portal to set."));
}
#endif
}
else
{
// Enter CP only if no stored SSID on flash and file
Serial.println(F("Open Config Portal without Timeout: No stored Credentials."));
initialConfig = true;
}
if (drd->detectDoubleReset())
{
// DRD, disable timeout.
ESPAsync_wifiManager.setConfigPortalTimeout(0);
Serial.println(F("Open Config Portal without Timeout: Double Reset Detected"));
initialConfig = true;
}
if (initialConfig)
{
Serial.print(F("Starting configuration portal @ "));
#if USE_CUSTOM_AP_IP
Serial.print(APStaticIP);
#else
Serial.print(F("192.168.4.1"));
#endif
Serial.print(F(", SSID = "));
Serial.print(ssid);
Serial.print(F(", PWD = "));
Serial.println(password);
#if DISPLAY_STORED_CREDENTIALS_IN_CP
// New. Update Credentials, got from loadConfigData(), to display on CP
ESPAsync_wifiManager.setCredentials(WM_config.WiFi_Creds[0].wifi_ssid, WM_config.WiFi_Creds[0].wifi_pw,
WM_config.WiFi_Creds[1].wifi_ssid, WM_config.WiFi_Creds[1].wifi_pw);
#endif
// Starts an access point
if (!ESPAsync_wifiManager.startConfigPortal((const char *) ssid.c_str(), password.c_str()))
Serial.println(F("Not connected to WiFi but continuing anyway."));
else
{
Serial.println(F("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 = ESPAsync_wifiManager.getSSID(i);
String tempPW = ESPAsync_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);
}
}
#if USE_ESP_WIFIMANAGER_NTP
String tempTZ = ESPAsync_wifiManager.getTimezoneName();
if (strlen(tempTZ.c_str()) < sizeof(WM_config.TZ_Name) - 1)
strcpy(WM_config.TZ_Name, tempTZ.c_str());
else
strncpy(WM_config.TZ_Name, tempTZ.c_str(), sizeof(WM_config.TZ_Name) - 1);
const char * TZ_Result = ESPAsync_wifiManager.getTZ(WM_config.TZ_Name);
if (strlen(TZ_Result) < sizeof(WM_config.TZ) - 1)
strcpy(WM_config.TZ, TZ_Result);
else
strncpy(WM_config.TZ, TZ_Result, sizeof(WM_config.TZ_Name) - 1);
if ( strlen(WM_config.TZ_Name) > 0 )
{
LOGERROR3(F("Saving current TZ_Name ="), WM_config.TZ_Name, F(", TZ = "), WM_config.TZ);
#if ESP8266
configTime(WM_config.TZ, "pool.ntp.org");
#else
//configTzTime(WM_config.TZ, "pool.ntp.org" );
configTzTime(WM_config.TZ, "time.nist.gov", "0.pool.ntp.org", "1.pool.ntp.org");
#endif
}
else
{
LOGERROR(F("Current Timezone Name is not set. Enter Config Portal to set."));
}
#endif
// New in v1.4.0
ESPAsync_wifiManager.getSTAStaticIPConfig(WM_STA_IPconfig);
//////
saveConfigData();
}
startedAt = millis();
if (!initialConfig)
{
// Load stored data, the addAP ready for MultiWiFi reconnection
if (!configDataLoaded)
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 )
{
Serial.println(F("ConnectMultiWiFi in setup"));
connectMultiWiFi();
}
}
Serial.print(F("After waiting "));
Serial.print((float) (millis() - startedAt) / 1000);
Serial.print(F(" secs more in setup(), connection result is "));
if (WiFi.status() == WL_CONNECTED)
{
Serial.print(F("connected. Local IP: "));
Serial.println(WiFi.localIP());
}
else
Serial.println(ESPAsync_wifiManager.getStatus(WiFi.status()));
if ( !MDNS.begin(host.c_str()) )
{
Serial.println(F("Error starting MDNS responder!"));
}
// Add service to MDNS-SD
MDNS.addService("http", "tcp", HTTP_PORT);
//SERVER INIT
events.onConnect([](AsyncEventSourceClient * client)
{
client->send("hello!", NULL, millis(), 1000);
});
server.addHandler(&events);
server.on("/heap", HTTP_GET, [](AsyncWebServerRequest * request)
{
request->send(200, "text/plain", String(ESP.getFreeHeap()));
});
server.addHandler(new SPIFFSEditor(FileFS, http_username, http_password));
server.serveStatic("/", FileFS, "/").setDefaultFile("index.htm");
server.onNotFound([](AsyncWebServerRequest * request)
{
Serial.print(F("NOT_FOUND: "));
if (request->method() == HTTP_GET)
Serial.print(F("GET"));
else if (request->method() == HTTP_POST)
Serial.print(F("POST"));
else if (request->method() == HTTP_DELETE)
Serial.print(F("DELETE"));
else if (request->method() == HTTP_PUT)
Serial.print(F("PUT"));
else if (request->method() == HTTP_PATCH)
Serial.print(F("PATCH"));
else if (request->method() == HTTP_HEAD)
Serial.print(F("HEAD"));
else if (request->method() == HTTP_OPTIONS)
Serial.print(F("OPTIONS"));
else
Serial.print(F("UNKNOWN"));
Serial.println(" http://" + request->host() + request->url());
if (request->contentLength())
{
Serial.println("_CONTENT_TYPE: " + request->contentType());
Serial.println("_CONTENT_LENGTH: " + request->contentLength());
}
int headers = request->headers();
int i;
for (i = 0; i < headers; i++)
{
AsyncWebHeader* h = request->getHeader(i);
Serial.println("_HEADER[" + h->name() + "]: " + h->value());
}
int params = request->params();
for (i = 0; i < params; i++)
{
AsyncWebParameter* p = request->getParam(i);
if (p->isFile())
{
Serial.println("_FILE[" + p->name() + "]: " + p->value() + ", size: " + p->size());
}
else if (p->isPost())
{
Serial.println("_POST[" + p->name() + "]: " + p->value());
}
else
{
Serial.println("_GET[" + p->name() + "]: " + p->value());
}
}
request->send(404);
});
server.onFileUpload([](AsyncWebServerRequest * request, const String & filename, size_t index, uint8_t *data, size_t len, bool final)
{
(void) request;
if (!index)
Serial.println("UploadStart: " + filename);
Serial.print((const char*)data);
if (final)
Serial.println("UploadEnd: " + filename + "(" + String(index + len) + ")" );
});
server.onRequestBody([](AsyncWebServerRequest * request, uint8_t *data, size_t len, size_t index, size_t total)
{
(void) request;
if (!index)
Serial.println("BodyStart: " + total);
Serial.print((const char*)data);
if (index + len == total)
Serial.println("BodyEnd: " + total);
});
server.begin();
//////
Serial.print(F("HTTP server started @ "));
Serial.println(WiFi.localIP());
Serial.println(separatorLine);
Serial.print("Open http://"); Serial.print(WiFi.localIP());
Serial.println("/edit to see the file browser");
Serial.println("Using username = " + http_username + " and password = " + http_password);
Serial.println(separatorLine);
digitalWrite(LED_BUILTIN, LED_OFF);
}
void loop()
{
// Call the double reset detector loop method every so often,
// so that it can recognise when the timeout expires.
// You can also call drd.stop() when you wish to no longer
// consider the next reset as a double reset.
if (drd)
drd->loop();
check_status();
}