Merge pull request #32 from rjwats/ft_autoreconnect

Fix Access Point Issues
This commit is contained in:
rjwats 2019-06-07 20:30:02 +01:00 committed by GitHub
commit 067ca81315
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 120 additions and 63 deletions

View File

@ -1,5 +1,5 @@
{ {
"ssid":"ssid", "ssid":"",
"password":"password", "password":"password",
"hostname":"esp8266-react", "hostname":"esp8266-react",
"static_ip_config":false "static_ip_config":false

View File

@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><link rel="stylesheet" href="/css/roboto.css"><link rel="manifest" href="/app/manifest.json"><title>ESP8266 React</title></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script src="/js/1.b351.js"></script><script src="/js/2.8ca9.js"></script><script src="/js/0.439a.js"></script></body></html> <!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><link rel="stylesheet" href="/css/roboto.css"><link rel="manifest" href="/app/manifest.json"><title>ESP8266 React</title></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script src="/js/1.b351.js"></script><script src="/js/2.8ca9.js"></script><script src="/js/0.40b9.js"></script></body></html>

BIN
data/www/js/0.40b9.js.gz Normal file

Binary file not shown.

Binary file not shown.

View File

@ -66,7 +66,7 @@ class APSettingsForm extends React.Component {
<Fragment> <Fragment>
<TextValidator <TextValidator
validators={['required', 'matchRegexp:^.{1,32}$']} validators={['required', 'matchRegexp:^.{1,32}$']}
errorMessages={['Access Point SSID is required', 'Access Point SSID must be 32 characeters or less']} errorMessages={['Access Point SSID is required', 'Access Point SSID must be 32 characters or less']}
name="ssid" name="ssid"
label="Access Point SSID" label="Access Point SSID"
className={classes.textField} className={classes.textField}

View File

@ -99,8 +99,8 @@ class WiFiSettingsForm extends React.Component {
{ {
selectedNetwork ? this.renderSelectedNetwork() : selectedNetwork ? this.renderSelectedNetwork() :
<TextValidator <TextValidator
validators={['required', 'matchRegexp:^.{1,32}$']} validators={['matchRegexp:^.{0,32}$']}
errorMessages={['SSID is required', 'SSID must be 32 characeters or less']} errorMessages={['SSID must be 32 characters or less']}
name="ssid" name="ssid"
label="SSID" label="SSID"
className={classes.textField} className={classes.textField}

View File

@ -6,7 +6,7 @@ NTPSettingsService::NTPSettingsService(AsyncWebServer* server, FS* fs, SecurityM
_onStationModeDisconnectedHandler = WiFi.onStationModeDisconnected(std::bind(&NTPSettingsService::onStationModeDisconnected, this, std::placeholders::_1)); _onStationModeDisconnectedHandler = WiFi.onStationModeDisconnected(std::bind(&NTPSettingsService::onStationModeDisconnected, this, std::placeholders::_1));
_onStationModeGotIPHandler = WiFi.onStationModeGotIP(std::bind(&NTPSettingsService::onStationModeGotIP, this, std::placeholders::_1)); _onStationModeGotIPHandler = WiFi.onStationModeGotIP(std::bind(&NTPSettingsService::onStationModeGotIP, this, std::placeholders::_1));
#elif defined(ESP_PLATFORM) #elif defined(ESP_PLATFORM)
WiFi.onEvent(std::bind(&NTPSettingsService::onStationModeDisconnected, this, std::placeholders::_1, std::placeholders::_2), WiFiEvent_t::SYSTEM_EVENT_AP_STADISCONNECTED); WiFi.onEvent(std::bind(&NTPSettingsService::onStationModeDisconnected, this, std::placeholders::_1, std::placeholders::_2), WiFiEvent_t::SYSTEM_EVENT_STA_DISCONNECTED);
WiFi.onEvent(std::bind(&NTPSettingsService::onStationModeGotIP, this, std::placeholders::_1, std::placeholders::_2), WiFiEvent_t::SYSTEM_EVENT_STA_GOT_IP); WiFi.onEvent(std::bind(&NTPSettingsService::onStationModeGotIP, this, std::placeholders::_1, std::placeholders::_2), WiFiEvent_t::SYSTEM_EVENT_STA_GOT_IP);
#endif #endif

View File

@ -39,6 +39,7 @@ void OTASettingsService::writeToJsonObject(JsonObject& root) {
void OTASettingsService::configureArduinoOTA() { void OTASettingsService::configureArduinoOTA() {
if (_arduinoOTA){ if (_arduinoOTA){
_arduinoOTA->end();
delete _arduinoOTA; delete _arduinoOTA;
_arduinoOTA = nullptr; _arduinoOTA = nullptr;
} }

View File

@ -1,6 +1,12 @@
#include <WiFiSettingsService.h> #include <WiFiSettingsService.h>
WiFiSettingsService::WiFiSettingsService(AsyncWebServer* server, FS* fs, SecurityManager* securityManager) : AdminSettingsService(server, fs, securityManager, WIFI_SETTINGS_SERVICE_PATH, WIFI_SETTINGS_FILE) {} WiFiSettingsService::WiFiSettingsService(AsyncWebServer* server, FS* fs, SecurityManager* securityManager) : AdminSettingsService(server, fs, securityManager, WIFI_SETTINGS_SERVICE_PATH, WIFI_SETTINGS_FILE) {
#if defined(ESP8266)
_onStationModeDisconnectedHandler = WiFi.onStationModeDisconnected(std::bind(&WiFiSettingsService::onStationModeDisconnected, this, std::placeholders::_1));
#elif defined(ESP_PLATFORM)
WiFi.onEvent(std::bind(&WiFiSettingsService::onStationModeDisconnected, this, std::placeholders::_1, std::placeholders::_2), WiFiEvent_t::SYSTEM_EVENT_STA_DISCONNECTED);
#endif
}
WiFiSettingsService::~WiFiSettingsService() {} WiFiSettingsService::~WiFiSettingsService() {}
@ -56,27 +62,11 @@ void WiFiSettingsService::onConfigUpdated() {
} }
void WiFiSettingsService::reconfigureWiFiConnection() { void WiFiSettingsService::reconfigureWiFiConnection() {
Serial.println("Reconfiguring WiFi..."); // disconnect and de-configure wifi
// disconnect and de-configure wifi and software access point
WiFi.disconnect(true); WiFi.disconnect(true);
// configure for static IP // reset last connection attempt to force loop to reconnect immediately
if (_staticIPConfig) { _lastConnectionAttempt = 0;
WiFi.config(_localIP, _gatewayIP, _subnetMask, _dnsIP1, _dnsIP2);
} else {
// configure for DHCP
#if defined(ESP8266)
WiFi.config(INADDR_ANY, INADDR_ANY, INADDR_ANY);
WiFi.hostname(_hostname);
#elif defined(ESP_PLATFORM)
WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE);
WiFi.setHostname(_hostname.c_str());
#endif
}
// connect to the network
WiFi.begin(_ssid.c_str(), _password.c_str());
} }
void WiFiSettingsService::readIP(JsonObject& root, String key, IPAddress& _ip){ void WiFiSettingsService::readIP(JsonObject& root, String key, IPAddress& _ip){
@ -90,3 +80,48 @@ void WiFiSettingsService::writeIP(JsonObject& root, String key, IPAddress& _ip){
root[key] = _ip.toString(); root[key] = _ip.toString();
} }
} }
void WiFiSettingsService::loop() {
unsigned long currentMillis = millis();
if (!_lastConnectionAttempt || (unsigned long)(currentMillis - _lastConnectionAttempt) >= WIFI_RECONNECTION_DELAY) {
_lastConnectionAttempt = currentMillis;
manageSTA();
}
}
void WiFiSettingsService::manageSTA() {
// Abort if already connected, or if we have no SSID
if (WiFi.isConnected() || _ssid.length() == 0) {
return;
}
// Connect or reconnect as required
if ((WiFi.getMode() & WIFI_STA) == 0) {
Serial.println("Connecting to WiFi.");
if (_staticIPConfig) {
// configure for static IP
WiFi.config(_localIP, _gatewayIP, _subnetMask, _dnsIP1, _dnsIP2);
} else {
// configure for DHCP
#if defined(ESP8266)
WiFi.config(INADDR_ANY, INADDR_ANY, INADDR_ANY);
WiFi.hostname(_hostname);
#elif defined(ESP_PLATFORM)
WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE);
WiFi.setHostname(_hostname.c_str());
#endif
}
// attempt to connect to the network
WiFi.begin(_ssid.c_str(), _password.c_str());
}
}
#if defined(ESP8266)
void WiFiSettingsService::onStationModeDisconnected(const WiFiEventStationModeDisconnected& event) {
WiFi.disconnect(true);
}
#elif defined(ESP_PLATFORM)
void WiFiSettingsService::onStationModeDisconnected(WiFiEvent_t event, WiFiEventInfo_t info) {
WiFi.disconnect(true);
}
#endif

View File

@ -6,6 +6,7 @@
#define WIFI_SETTINGS_FILE "/config/wifiSettings.json" #define WIFI_SETTINGS_FILE "/config/wifiSettings.json"
#define WIFI_SETTINGS_SERVICE_PATH "/rest/wifiSettings" #define WIFI_SETTINGS_SERVICE_PATH "/rest/wifiSettings"
#define WIFI_RECONNECTION_DELAY 1000 * 60
class WiFiSettingsService : public AdminSettingsService { class WiFiSettingsService : public AdminSettingsService {
@ -15,13 +16,13 @@ class WiFiSettingsService : public AdminSettingsService {
~WiFiSettingsService(); ~WiFiSettingsService();
void begin(); void begin();
void loop();
protected: protected:
void readFromJsonObject(JsonObject& root); void readFromJsonObject(JsonObject& root);
void writeToJsonObject(JsonObject& root); void writeToJsonObject(JsonObject& root);
void onConfigUpdated(); void onConfigUpdated();
void reconfigureWiFiConnection();
private: private:
// connection settings // connection settings
@ -30,6 +31,9 @@ class WiFiSettingsService : public AdminSettingsService {
String _hostname; String _hostname;
bool _staticIPConfig; bool _staticIPConfig;
// for the mangement delay loop
unsigned long _lastConnectionAttempt;
// optional configuration for static IP address // optional configuration for static IP address
IPAddress _localIP; IPAddress _localIP;
IPAddress _gatewayIP; IPAddress _gatewayIP;
@ -37,8 +41,17 @@ class WiFiSettingsService : public AdminSettingsService {
IPAddress _dnsIP1; IPAddress _dnsIP1;
IPAddress _dnsIP2; IPAddress _dnsIP2;
#if defined(ESP8266)
WiFiEventHandler _onStationModeDisconnectedHandler;
void onStationModeDisconnected(const WiFiEventStationModeDisconnected& event);
#elif defined(ESP_PLATFORM)
void onStationModeDisconnected(WiFiEvent_t event, WiFiEventInfo_t info);
#endif
void readIP(JsonObject& root, String key, IPAddress& _ip); void readIP(JsonObject& root, String key, IPAddress& _ip);
void writeIP(JsonObject& root, String key, IPAddress& _ip); void writeIP(JsonObject& root, String key, IPAddress& _ip);
void reconfigureWiFiConnection();
void manageSTA();
}; };

View File

@ -10,7 +10,7 @@
#endif #endif
#include <FS.h> #include <FS.h>
#include <esp_wifi.h>
#include <SecuritySettingsService.h> #include <SecuritySettingsService.h>
#include <WiFiSettingsService.h> #include <WiFiSettingsService.h>
#include <APSettingsService.h> #include <APSettingsService.h>
@ -41,51 +41,59 @@ APStatus apStatus = APStatus(&server, &securitySettingsService);
SystemStatus systemStatus = SystemStatus(&server, &securitySettingsService);; SystemStatus systemStatus = SystemStatus(&server, &securitySettingsService);;
void setup() { void setup() {
// Disable wifi config persistance // Disable wifi config persistance and auto reconnect
WiFi.persistent(false); WiFi.persistent(false);
WiFi.setAutoReconnect(false);
Serial.begin(SERIAL_BAUD_RATE); #if defined(ESP_PLATFORM)
SPIFFS.begin(); // Init the wifi driver on ESP32
WiFi.mode(WIFI_MODE_MAX);
WiFi.mode(WIFI_MODE_NULL);
#endif
// start security settings service first Serial.begin(SERIAL_BAUD_RATE);
securitySettingsService.begin(); SPIFFS.begin();
// Start security settings service first
securitySettingsService.begin();
// start services // Start services
ntpSettingsService.begin(); ntpSettingsService.begin();
otaSettingsService.begin(); otaSettingsService.begin();
apSettingsService.begin(); apSettingsService.begin();
wifiSettingsService.begin(); wifiSettingsService.begin();
// Serving static resources from /www/ // Serving static resources from /www/
server.serveStatic("/js/", SPIFFS, "/www/js/"); server.serveStatic("/js/", SPIFFS, "/www/js/");
server.serveStatic("/css/", SPIFFS, "/www/css/"); server.serveStatic("/css/", SPIFFS, "/www/css/");
server.serveStatic("/fonts/", SPIFFS, "/www/fonts/"); server.serveStatic("/fonts/", SPIFFS, "/www/fonts/");
server.serveStatic("/app/", SPIFFS, "/www/app/"); server.serveStatic("/app/", SPIFFS, "/www/app/");
server.serveStatic("/favicon.ico", SPIFFS, "/www/favicon.ico"); server.serveStatic("/favicon.ico", SPIFFS, "/www/favicon.ico");
// Serving all other get requests with "/www/index.htm" // Serving all other get requests with "/www/index.htm"
// OPTIONS get a straight up 200 response // OPTIONS get a straight up 200 response
server.onNotFound([](AsyncWebServerRequest *request) { server.onNotFound([](AsyncWebServerRequest *request) {
if (request->method() == HTTP_GET) { if (request->method() == HTTP_GET) {
request->send(SPIFFS, "/www/index.html"); request->send(SPIFFS, "/www/index.html");
} else if (request->method() == HTTP_OPTIONS) { } else if (request->method() == HTTP_OPTIONS) {
request->send(200); request->send(200);
} else { } else {
request->send(404); request->send(404);
} }
}); });
// Disable CORS if required // Disable CORS if required
#if defined(ENABLE_CORS) #if defined(ENABLE_CORS)
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", CORS_ORIGIN); DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", CORS_ORIGIN);
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Headers", "Accept, Content-Type, Authorization"); DefaultHeaders::Instance().addHeader("Access-Control-Allow-Headers", "Accept, Content-Type, Authorization");
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Credentials", "true"); DefaultHeaders::Instance().addHeader("Access-Control-Allow-Credentials", "true");
#endif #endif
server.begin(); server.begin();
} }
void loop() { void loop() {
wifiSettingsService.loop();
apSettingsService.loop(); apSettingsService.loop();
ntpSettingsService.loop(); ntpSettingsService.loop();
otaSettingsService.loop(); otaSettingsService.loop();