diff --git a/PersWiFiManager.cpp b/PersWiFiManager.cpp
new file mode 100644
index 0000000..416eff8
--- /dev/null
+++ b/PersWiFiManager.cpp
@@ -0,0 +1,102 @@
+#include "PersWiFiManager.h"
+
+#ifdef WIFI_HTM_PROGMEM
+const char wifi_htm[] PROGMEM = R"=====(
ESP WiFi)=====";
+#endif
+
+PersWiFiManager::PersWiFiManager(ESP8266WebServer& s, DNSServer& d, const String& apSSID) {
+ _server = &s;
+ _dnsServer = &d;
+ _apSSID = apSSID;
+}
+
+void PersWiFiManager::attemptConnection(const String& ssid, const String& pass) {
+ IPAddress apIP(192, 168, 1, 1);
+ //attempt to connect to wifi
+ WiFi.mode(WIFI_STA);
+ if (ssid.length()) {
+ if (pass.length()) WiFi.begin(ssid.c_str(), pass.c_str());
+ else WiFi.begin(ssid.c_str());
+ } else {
+ WiFi.begin();
+ }
+ unsigned long connectTime = millis();
+ //while ((millis() - connectTime) < 1000 * WIFI_CONNECT_TIMEOUT && WiFi.status() != WL_CONNECTED)
+ while (WiFi.status() != WL_CONNECT_FAILED && WiFi.status() != WL_CONNECTED && (millis() - connectTime) < 1000 * WIFI_CONNECT_TIMEOUT)
+ delay(10);
+ if (WiFi.status() != WL_CONNECTED) { //if timed out, switch to AP mode
+ WiFi.mode(WIFI_AP);
+ WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
+ WiFi.softAP(_apSSID.length() ? _apSSID.c_str() : "ESP8266");
+ } //if
+ _dnsServer->setErrorReplyCode(DNSReplyCode::NoError);
+ _dnsServer->start((byte)53, "*", apIP); //used for captive portal in AP mode
+}
+
+void PersWiFiManager::attemptConnection() {
+ PersWiFiManager::attemptConnection("", "");
+}
+
+void PersWiFiManager::setupWiFiHandlers() {
+ _server->on("/wifi/list", [&] () {
+ //scan for wifi networks
+ int n = WiFi.scanNetworks();
+
+ //build array of indices
+ int ix[n];
+ for (int i = 0; i < n; i++) ix[i] = i;
+
+ //sort by signal strength
+ for (int i = 0; i < n; i++) for (int j = 1; j < n - i; j++) if (WiFi.RSSI(ix[j]) > WiFi.RSSI(ix[j - 1])) std::swap(ix[j], ix[j - 1]);
+ //remove duplicates
+ for (int i = 0; i < n; i++) for (int j = i + 1; j < n; j++) if (WiFi.SSID(ix[i]).equals(WiFi.SSID(ix[j])) && WiFi.encryptionType(ix[i]) == WiFi.encryptionType(ix[j])) ix[j] = -1;
+
+ //build plain text string of wifi info
+ //format [signal%]:[encrypted 0 or 1]:SSID
+ String s = "";
+ s.reserve(2050);
+ for (int i = 0; i < n && s.length() < 2000; i++) { //check s.length to limit memory usage
+ if (ix[i] != -1) {
+ s += String(i ? "\n" : "") + ((constrain(WiFi.RSSI(ix[i]), -100, -50) + 100) * 2) + ","
+ + ((WiFi.encryptionType(ix[i]) == ENC_TYPE_NONE) ? 0 : 1) + "," + WiFi.SSID(ix[i]);
+ }
+ }
+
+ //send string to client
+ _server->send(200, "text/plain", s);
+ }); //_server->on /wifi/list
+
+ _server->on("/wifi/wps", [&]() {
+ _server->send(200, "text/html", "attempting WPS");
+ WiFi.mode(WIFI_STA);
+ WiFi.beginWPSConfig();
+ delay(100);
+ if (WiFi.status() != WL_CONNECTED) {
+ attemptConnection("", "");
+ }
+ }); //_server->on /wifi/wps
+
+ _server->on("/wifi/connect", [&]() {
+ _server->send(200, "text/html", "connecting...");
+ attemptConnection(_server->arg("n"), _server->arg("p"));
+ }); //_server->on /wifi/connect
+
+ _server->on("/wifi/rst", [&]() {
+ _server->send(200, "text/html", "Rebooting...");
+ delay(100);
+ ESP.restart();
+ });
+
+#ifdef WIFI_HTM_PROGMEM
+ _server->on("/wifi.htm", [&]() {
+ _server->send(200, "text/html", wifi_htm);
+ });
+#endif
+
+}//setupWiFiHandlers
+
+void PersWiFiManager::begin() {
+ attemptConnection();
+ setupWiFiHandlers();
+}//begin
+
diff --git a/PersWiFiManager.h b/PersWiFiManager.h
new file mode 100644
index 0000000..fc5d647
--- /dev/null
+++ b/PersWiFiManager.h
@@ -0,0 +1,32 @@
+#ifndef PERSWIFIMANAGER_H
+#define PERSWIFIMANAGER_H
+
+#include
+#include
+#include
+
+#define WIFI_CONNECT_TIMEOUT 30
+
+class PersWiFiManager {
+
+ public:
+ //constructor - takes inputs for ESP8266WebServer and DNSServer, optional ap ssid
+ PersWiFiManager(ESP8266WebServer& s, DNSServer& d, const String& apSSID);
+ PersWiFiManager(ESP8266WebServer& s, DNSServer& d): PersWiFiManager(s, d, "ESP8266") {};
+
+ void attemptConnection();
+ void attemptConnection(const String& ssid, const String& pass);
+
+ void setupWiFiHandlers();
+
+ void begin();
+
+ private:
+ ESP8266WebServer * _server;
+ DNSServer * _dnsServer;
+ String _apSSID;
+
+};//class
+
+#endif
+