-
Notifications
You must be signed in to change notification settings - Fork 32
/
WiFiManager.h
247 lines (196 loc) · 14.4 KB
/
WiFiManager.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
/**************************************************************
WiFiManager is a library for the ESP8266/Arduino platform
(https://github.com/esp8266/Arduino) to enable easy
configuration and reconfiguration of WiFi credentials using a Captive Portal
inspired by:
http://www.esp8266.com/viewtopic.php?f=29&t=2520
https://github.com/chriscook8/esp-arduino-apboot
https://github.com/esp8266/Arduino/tree/esp8266/hardware/esp8266com/esp8266/libraries/DNSServer/examples/CaptivePortalAdvanced
Built by AlexT https://github.com/tzapu
Licensed under MIT license
**************************************************************/
#ifndef WiFiManager_h
#define WiFiManager_h
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <DNSServer.h>
#include <memory>
#undef min
#undef max
#include <algorithm>
extern "C" {
#include "user_interface.h"
}
// DS3231 Library functions
#include "RtcDS3231.h"
extern RtcDS3231 Rtc;
extern String WPassword;
extern String Wssid;
extern String stationName;
extern float altitude_meters;
extern String adminPassword;
void writeEEPROMState();
void updateDisplay(int displayType);
/*
const char HTTP_200[] PROGMEM = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
const char HTTP_HEAD[] PROGMEM = "<!DOCTYPE html><html lang=\"en\"><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"/><title>{v}</title>";
const char HTTP_STYLE[] PROGMEM = "<style>div,input{padding:5px;font-size:1em;} input{width:95%;} body{text-align: center;} button{border:0;border-radius:0.3rem;background-color:#1fa3ec;color:#fff;line-height:2.4rem;font-size:1.2rem;width:100%;}</style>";
const char HTTP_SCRIPT[] PROGMEM = "<script>function c(l){document.getElementById('s').value=l.innerText||l.textContent;document.getElementById('p').focus();}</script>";
const char HTTP_HEAD_END[] PROGMEM = "</head><body><div style='text-align: left; display: inline-block;'>";
const char HTTP_PORTAL_OPTIONS[] PROGMEM = "SwitchDoc Labs OurWeather<BR><form action=\"wifi\" method=\"get\"><button>Configure WiFi</button></form><br/><form action=\"0wifi\" method=\"get\"><button>Configure WiFi (No Scan)</button></form>";
const char HTTP_ITEM[] PROGMEM = "<div><a href='#' onclick='c(this)'>{v}</a> {r}% {i}</div>";
const char HTTP_ITEM_PADLOCK[] PROGMEM = "<img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAKCAMAAAC+Ge+yAAAACVBMVEUAAAC7u7v///9etNz6AAAAI0lEQVQI133GsQ3AMAAEoXv2H9qNJacKFbEaWTQJ+uQB/nMdEaYAXeJkZ9AAAAAASUVORK5CYII='/>";
const char HTTP_FORM[] PROGMEM = "<form method='get' action='wifisave'><input id='n' name='n' length=32 placeholder='your Station Name'>Station Name<br/><input id='s' name='s' length=32 placeholder='WiFi SSID'>Local WiFi name<br/><input id='p' name='p' length=64 placeholder='WiFi password'>WiFi Password<br/><br/><input id='a' name='a' length=64 placeholder='altitude in meters'>Alt in Meters<br/><br/><input id='d' name='d' length=64 placeholder='Mmm dd yyyy'>Set Date Example: Jan 07 2016<br/><br/><input id='t' name='t' length=64 placeholder='hh:mm:ss'>Set Time (hh:mm:ss) 24 hour time<br/><br/><button type='submit'>save</button></form>";
const char HTTP_SAVED[] PROGMEM = "<div>Credentials Saved<br />Trying to connect OurWeather to network.<br />If it fails reconnect to AP, reset to try again</div>";
const char HTTP_END[] PROGMEM = "</div></body></html>";
*/
const char HTTP_200[] PROGMEM = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
const char HTTP_HEAD[] PROGMEM = "<!DOCTYPE html><html lang=\"en\"><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\"/><title>{v}</title>";
const char HTTP_STYLE[] PROGMEM = "<style>.c{text-align: center;} div,input{padding:5px;font-size:1em;} input{width:95%;} body{text-align: center;font-family:verdana;} button{border:0;border-radius:0.3rem;background-color:#1fa3ec;color:#fff;line-height:2.4rem;font-size:1.2rem;width:100%;} .q{float: right;width: 64px;text-align: right;} .l{background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAALVBMVEX///8EBwfBwsLw8PAzNjaCg4NTVVUjJiZDRUUUFxdiZGSho6OSk5Pg4eFydHTCjaf3AAAAZElEQVQ4je2NSw7AIAhEBamKn97/uMXEGBvozkWb9C2Zx4xzWykBhFAeYp9gkLyZE0zIMno9n4g19hmdY39scwqVkOXaxph0ZCXQcqxSpgQpONa59wkRDOL93eAXvimwlbPbwwVAegLS1HGfZAAAAABJRU5ErkJggg==\") no-repeat left center;background-size: 1em;}</style>";
const char HTTP_SCRIPT[] PROGMEM = "<script>function c(l){document.getElementById('s').value=l.innerText||l.textContent;document.getElementById('p').focus();}</script>";
const char HTTP_HEAD_END[] PROGMEM = "</head><body><div style='text-align:left;display:inline-block;min-width:260px;'>";
//const char HTTP_PORTAL_OPTIONS[] PROGMEM = "SwitchDoc Labs OurWeather<BR><form action=\"wifi\" method=\"get\"><button>Configure WiFi</button></form><br/><form action=\"0wifi\" method=\"get\"><button>Configure WiFi (No Scan)</button></form>";
const char HTTP_PORTAL_OPTIONS[] PROGMEM = "SwitchDoc Labs OurWeather<BR><form action=\"wifi\" method=\"get\"><button>Configure WiFi</button></form>";
//const char HTTP_PORTAL_OPTIONS[] PROGMEM = "<form action=\"/wifi\" method=\"get\"><button>Configure WiFi</button></form><br/><form action=\"/0wifi\" method=\"get\"><button>Configure WiFi (No Scan)</button></form><br/><form action=\"/i\" method=\"get\"><button>Info</button></form><br/><form action=\"/r\" method=\"post\"><button>Reset</button></form>";
const char HTTP_ITEM[] PROGMEM = "<div><a href='#p' onclick='c(this)'>{v}</a> <span class='q {i}'>{r}%</span></div>";
//const char HTTP_ITEM_PADLOCK[] PROGMEM = "<img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAALVBMVEX///8EBwfBwsLw8PAzNjaCg4NTVVUjJiZDRUUUFxdiZGSho6OSk5Pg4eFydHTCjaf3AAAAZElEQVQ4je2NSw7AIAhEBamKn97/uMXEGBvozkWb9C2Zx4xzWykBhFAeYp9gkLyZE0zIMno9n4g19hmdY39scwqVkOXaxph0ZCXQcqxSpgQpONa59wkRDOL93eAXvimwlbPbwwVAegLS1HGfZAAAAABJRU5ErkJggg==' width='13px'/>";
const char HTTP_FORM_START[] PROGMEM = "<form method='get' action='wifisave'><input id='n' name='n' length=32 placeholder='your Station Name'>Your Station Name<br/><input id='s' name='s' length=32 placeholder='WiFi SSID'> WiFi Name<br/><input id='p' name='p' length=64 placeholder='WiFi password'>WiFi Password<br/><br/><input id='a' name='a' length=64 placeholder='altitude in meters'>Alt in Meters<br/><br/><input id='d' name='d' length=64 placeholder='Mmm dd yyyy'> Set Date - Example: Jan 07 2016<br/><br/><input id='t' name='t' length=64 placeholder='hh:mm:ss'>Set Time (24 Hour Clock)";
const char HTTP_FORM_PARAM[] PROGMEM = "<br/><br/><input id='a' name='a' length=64 placeholder='altitude in meters'><br/><br/><input id='d' name='d' length=64 placeholder='Mmm dd yyyy'> Example: Jan 07 2016<br/><br/><input id='t' name='t' length=64 placeholder='hh:mm:ss'>";
const char HTTP_FORM_END[] PROGMEM = "<br/><br/><button type='submit'>save</button></form>";
//const char HTTP_FORM_START[] PROGMEM = "<form method='get' action='wifisave'><input id='n' name='n' length=32 placeholder='your Station Name'>Your Station Name<br/><input id='s' name='s' length=32 placeholder='WiFi SSID'>WiFi Name<br/><input id='p' name='p' length=64 placeholder='WiFi password'>WiFi Password<br/><br/><input id='a' name='a' length=64 placeholder='altitude in meters'>Alt in Meters<br/><br/>";
//const char HTTP_FORM_PARAM[] PROGMEM = "<input id='d' name='d' length=64 placeholder='Mmm dd yyyy'> Set Date - Example: Jan 07 2016<br/><br/><input id='t' name='t' length=64 placeholder='hh:mm:ss'>Set Time (hh:mm:ss) - 24 Hour Clock<br/><br/><button type='submit'>save</button></form>";
//const char HTTP_FORM_END[] PROGMEM = "<br/><button type='submit'>save</button></form>";
//const char HTTP_FORM[] PROGMEM = "<form method='get' action='wifisave'><input id='n' name='n' length=32 placeholder='your Station Name'><br/><input id='s' name='s' length=32 placeholder='WiFi SSID'><br/><input id='p' name='p' length=64 placeholder='WiFi password'><br/><br/><input id='a' name='a' length=64 placeholder='altitude in meters'><br/><br/><input id='d' name='d' length=64 placeholder='Mmm dd yyyy'> Example: Jan 07 2016<br/><br/><input id='t' name='t' length=64 placeholder='hh:mm:ss'><br/><br/><button type='submit'>save</button></form>";
const char HTTP_SCAN_LINK[] PROGMEM = "<br/><div class=\"c\"><a href=\"/wifi\">Scan</a></div>";
const char HTTP_SAVED[] PROGMEM = "<div>Credentials Saved<br />Trying to connect OurWeather to network.<br />If it fails, reconnect to 192.168.4.1 and repeat the procedure to try again</div>";
const char HTTP_END[] PROGMEM = "</div></body></html>";
#define WIFI_MANAGER_MAX_PARAMS 10
class WiFiManagerParameter {
public:
WiFiManagerParameter(const char *custom);
WiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length);
WiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length, const char *custom);
const char *getID();
const char *getValue();
const char *getPlaceholder();
int getValueLength();
const char *getCustomHTML();
private:
const char *_id;
const char *_placeholder;
char *_value;
int _length;
const char *_customHTML;
void init(const char *id, const char *placeholder, const char *defaultValue, int length, const char *custom);
friend class WiFiManager;
};
class WiFiManager
{
public:
WiFiManager();
boolean autoConnect();
boolean autoConnect(char const *apName, char const *apPassword = NULL);
boolean justConnect(char const *apName, char const *apPassword = NULL);
//if you want to always start the config portal, without trying to connect first
boolean startConfigPortal(char const *apName, char const *apPassword = NULL);
// get the AP name of the config portal, so it can be used in the callback
String getConfigPortalSSID();
void resetSettings();
void blinkLED(int timesToBlink, int delayBetweenBlinks);
//sets timeout before webserver loop ends and exits even if there has been no setup.
//usefully for devices that failed to connect at some point and got stuck in a webserver loop
//in seconds setConfigPortalTimeout is a new name for setTimeout
void setConfigPortalTimeout(unsigned long seconds);
void setTimeout(unsigned long seconds);
//sets timeout for which to attempt connecting, usefull if you get a lot of failed connects
void setConnectTimeout(unsigned long seconds);
void setDebugOutput(boolean debug);
//defaults to not showing anything under 8% signal quality if called
void setMinimumSignalQuality(int quality = 8);
//sets a custom ip /gateway /subnet configuration
void setAPStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn);
//sets config for a static IP
void setSTAStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn);
//called when AP mode and config portal is started
// void setAPCallback( void (*func)(WiFiManager*) );
void setAPCallback( void (*func)(void) );
//called when settings have been changed and connection was successful
void setSaveConfigCallback( void (*func)(void) );
//adds a custom parameter
void addParameter(WiFiManagerParameter *p);
//if this is set, it will exit after config, even if connection is unsucessful.
void setBreakAfterConfig(boolean shouldBreak);
//if this is set, try WPS setup when starting (this will delay config portal for up to 2 mins)
//TODO
//if this is set, customise style
void setCustomHeadElement(const char* element);
private:
std::unique_ptr<DNSServer> dnsServer;
std::unique_ptr<ESP8266WebServer> server;
//const int WM_DONE = 0;
//const int WM_WAIT = 10;
//const String HTTP_HEAD = "<!DOCTYPE html><html lang=\"en\"><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"/><title>{v}</title>";
void setupConfigPortal();
#ifdef NO_EXTRA_4K_HEAP
void startWPS();
#endif
const char* _apName = "no-net";
const char* _apPassword = NULL;
String _ssid = "";
String _pass = "";
String _time = "";
String _date = "";
String _name = "";
String _altitude = "";
unsigned long _configPortalTimeout = 0;
unsigned long _connectTimeout = 0;
unsigned long _configPortalStart = 0;
IPAddress _ap_static_ip;
IPAddress _ap_static_gw;
IPAddress _ap_static_sn;
IPAddress _sta_static_ip;
IPAddress _sta_static_gw;
IPAddress _sta_static_sn;
int _paramsCount = 0;
int _minimumQuality = -1;
boolean _shouldBreakAfterConfig = false;
#ifdef NO_EXTRA_4K_HEAP
boolean _tryWPS = false;
#endif
const char* _customHeadElement = "";
//String getEEPROMString(int start, int len);
//void setEEPROMString(int start, int len, String string);
int status = WL_IDLE_STATUS;
int connectWifi(String ssid, String pass);
uint8_t waitForConnectResult();
void handleRoot();
void handleWifi(boolean scan);
void handleWifiSave();
void handleInfo();
void handleReset();
void handleNotFound();
void handle204();
boolean captivePortal();
// DNS server
const byte DNS_PORT = 53;
//helpers
int getRSSIasQuality(int RSSI);
boolean isIp(String str);
String toStringIp(IPAddress ip);
boolean connect;
boolean _debug = true;
void (*_apcallback)(WiFiManager*) = NULL;
void (*_savecallback)(void) = NULL;
WiFiManagerParameter* _params[WIFI_MANAGER_MAX_PARAMS];
template <typename Generic>
void DEBUG_WM(Generic text);
template <class T>
auto optionalIPFromString(T *obj, const char *s) -> decltype( obj->fromString(s) ) {
return obj->fromString(s);
}
auto optionalIPFromString(...) -> bool {
DEBUG_WM("NO fromString METHOD ON IPAddress, you need ESP8266 core 2.1.0 or newer for Custom IP configuration to work.");
return false;
}
};
#endif