diff --git a/README.md b/README.md index 5c34ebc..fca79af 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ First attempt at a library. Lots more changes and fixes to do. Contributions are - ~~cleanup and streamline code~~ (although this is ongoing) - if timeout is set, extend it when a page is fetched in AP mode - ~~add ability to configure more parameters than ssid/password~~ -- maybe allow setting ip of ESP after reboot +- ~~maybe allow setting ip of ESP after reboot~~ - ~~add to Arduino Boards Manager~~ - add to PlatformIO - add multiple sets of network credentials @@ -130,7 +130,9 @@ void configModeCallback (WiFiManager *myWiFiManager) { ``` ##### Save settings -This gets called when custom parameters have been set **AND** a connection has been established. Use it to set a flag, so when all the configuration finishes, you can save the extra parameters somewhere. See [AutoConnectWithFSParameters Example](https://github.com/tzapu/WiFiManager/tree/master/examples/AutoConnectWithFSParameters). +This gets called when custom parameters have been set **AND** a connection has been established. Use it to set a flag, so when all the configuration finishes, you can save the extra parameters somewhere. + +See [AutoConnectWithFSParameters Example](https://github.com/tzapu/WiFiManager/tree/master/examples/AutoConnectWithFSParameters). ```cpp wifiManager.setSaveConfigCallback(saveConfigCallback); ``` @@ -157,7 +159,8 @@ Check for connection and if it's still not established do whatever is needed (on #### On Demand Configuration Portal If you would rather start the configuration portal on demand rather than automatically on a failed connection attempt, then this is for you. -Instead of calling `autoConnect()` which does all the connecting and failover configuration portal setup for you, you need to use `startConfigPortal()` +Instead of calling `autoConnect()` which does all the connecting and failover configuration portal setup for you, you need to use `startConfigPortal()`. __Do not use BOTH.__ + Example usage ```cpp void loop() { @@ -245,8 +248,6 @@ wifiManager.setDebugOutput(false); ##### v0.2 needs the latest staging version (or at least a recent release of the staging version) to work -This is jsut random textTo show the lagginess. -[the editor is completly](behing the typing) ##### v0.1 works with the staging release ver. 1.6.5-1044-g170995a, built on Aug 10, 2015 of the ESP8266 Arduino library. diff --git a/WiFiManager.cpp b/WiFiManager.cpp index b43efff..a553a88 100644 --- a/WiFiManager.cpp +++ b/WiFiManager.cpp @@ -114,13 +114,6 @@ boolean WiFiManager::autoConnect(char const *apName, char const *apPassword) { // attempt to connect; should it fail, fall back to AP WiFi.mode(WIFI_STA); - // check if we've got static_ip settings, if we do, use those. - if (_sta_static_ip) { - DEBUG_WM(F("Custom STA IP/GW/Subnet")); - WiFi.config(_sta_static_ip, _sta_static_gw, _sta_static_sn); - DEBUG_WM(WiFi.localIP()); - } - if (connectWifi(ssid, pass) == WL_CONNECTED) { DEBUG_WM(F("IP Address:")); DEBUG_WM(WiFi.localIP()); @@ -154,9 +147,9 @@ boolean WiFiManager::startConfigPortal(char const *apName, char const *apPasswo if (connect) { + connect = false; delay(2000); DEBUG_WM(F("Connecting to new AP")); - connect = false; // using user-provided _ssid, _pass in place of system-stored ssid amd pass if (connectWifi(_ssid, _pass) != WL_CONNECTED) { DEBUG_WM(F("Failed to connect.")); @@ -184,7 +177,15 @@ boolean WiFiManager::startConfigPortal(char const *apName, char const *apPasswo int WiFiManager::connectWifi(String ssid, String pass) { DEBUG_WM(F("Connecting as wifi client...")); - //WiFi.disconnect(); + + // check if we've got static_ip settings, if we do, use those. + if (_sta_static_ip) { + DEBUG_WM(F("Custom STA IP/GW/Subnet")); + WiFi.config(_sta_static_ip, _sta_static_gw, _sta_static_sn); + DEBUG_WM(WiFi.localIP()); + } + + WiFi.begin(ssid.c_str(), pass.c_str()); int connRes = WiFi.waitForConnectResult(); DEBUG_WM ("Connection result: "); @@ -394,6 +395,38 @@ void WiFiManager::handleWifi(boolean scan) { server->sendContent_P("
"); } + if(_sta_static_ip) { + + String item = FPSTR(HTTP_FORM_PARAM); + item.replace("{i}", "ip"); + item.replace("{n}", "ip"); + item.replace("{p}", "Static IP"); + item.replace("{l}", "15"); + item.replace("{v}", _sta_static_ip.toString()); + + server->sendContent(item); + + item = FPSTR(HTTP_FORM_PARAM); + item.replace("{i}", "gw"); + item.replace("{n}", "gw"); + item.replace("{p}", "Static Gateway"); + item.replace("{l}", "15"); + item.replace("{v}", _sta_static_gw.toString()); + + server->sendContent(item); + + item = FPSTR(HTTP_FORM_PARAM); + item.replace("{i}", "sn"); + item.replace("{n}", "sn"); + item.replace("{p}", "Subnet"); + item.replace("{l}", "15"); + item.replace("{v}", _sta_static_sn.toString()); + + server->sendContent(item); + + server->sendContent_P("
"); + } + server->sendContent_P(HTTP_FORM_END); server->sendContent_P(HTTP_END); server->client().stop(); @@ -423,6 +456,22 @@ void WiFiManager::handleWifiSave() { DEBUG_WM(value); } + if(server->arg("ip") != "") { + DEBUG_WM(F("static ip")); + DEBUG_WM(server->arg("ip")); + _sta_static_ip.fromString(server->arg("ip")); + } + if(server->arg("gw")) { + DEBUG_WM(F("static gateway")); + DEBUG_WM(server->arg("gw")); + _sta_static_gw.fromString(server->arg("gw")); + } + if(server->arg("sn")) { + DEBUG_WM(F("static netmask")); + DEBUG_WM(server->arg("sn")); + _sta_static_sn.fromString(server->arg("sn")); + } + server->sendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); server->sendHeader("Pragma", "no-cache"); server->sendHeader("Expires", "-1"); diff --git a/WiFiManager.h b/WiFiManager.h index 1dc2e1e..35919e8 100644 --- a/WiFiManager.h +++ b/WiFiManager.h @@ -40,15 +40,15 @@ class WiFiManagerParameter { public: WiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length); - const char* getID(); - const char* getValue(); - const char* getPlaceholder(); - int getValueLength(); + const char *getID(); + const char *getValue(); + const char *getPlaceholder(); + int getValueLength(); private: - const char* _id; - const char* _placeholder; - char* _value; - int _length; + const char *_id; + const char *_placeholder; + char *_value; + int _length; friend class WiFiManager; }; diff --git a/examples/AutoConnectWithFSParametersAndCustomIP/AutoConnectWithFSParametersAndCustomIP.ino b/examples/AutoConnectWithFSParametersAndCustomIP/AutoConnectWithFSParametersAndCustomIP.ino new file mode 100644 index 0000000..bd44cbe --- /dev/null +++ b/examples/AutoConnectWithFSParametersAndCustomIP/AutoConnectWithFSParametersAndCustomIP.ino @@ -0,0 +1,193 @@ +#include //this needs to be first, or it all crashes and burns... + +#include //https://github.com/esp8266/Arduino + +//needed for library +#include +#include +#include //https://github.com/tzapu/WiFiManager + +#include //https://github.com/bblanchon/ArduinoJson + +//define your default values here, if there are different values in config.json, they are overwritten. +char mqtt_server[40]; +char mqtt_port[5] = "8080"; +char blynk_token[64] = "YOUR_BLYNK_TOKEN"; +//default custom static IP +char static_ip[18] = "10.0.1.56"; +char static_gw[18] = "10.0.1.1"; +char static_sn[18] = "255.255.255.0"; + +//flag for saving data +bool shouldSaveConfig = false; + +//callback notifying us of the need to save config +void saveConfigCallback () { + Serial.println("Should save config"); + shouldSaveConfig = true; +} + +void setup() { + // put your setup code here, to run once: + Serial.begin(115200); + Serial.println(); + + //clean FS, for testing + //SPIFFS.format(); + + //read configuration from FS json + Serial.println("mounting FS..."); + + if (SPIFFS.begin()) { + Serial.println("mounted file system"); + if (SPIFFS.exists("/config.json")) { + //file exists, reading and loading + Serial.println("reading config file"); + File configFile = SPIFFS.open("/config.json", "r"); + if (configFile) { + Serial.println("opened config file"); + size_t size = configFile.size(); + // Allocate a buffer to store contents of the file. + std::unique_ptr buf(new char[size]); + + configFile.readBytes(buf.get(), size); + StaticJsonBuffer<200> jsonBuffer; + JsonObject& json = jsonBuffer.parseObject(buf.get()); + json.printTo(Serial); + if (json.success()) { + Serial.println("\nparsed json"); + + strcpy(mqtt_server, json["mqtt_server"]); + strcpy(mqtt_port, json["mqtt_port"]); + strcpy(blynk_token, json["blynk_token"]); + + //mqtt_server = json["mqtt_server"]; + //mqtt_port = json["mqtt_port"]; + //blynk_token = json["blynk_token"]; + + if(json["ip"]) { + Serial.println("setting custom ip from config"); + //static_ip = json["ip"]; + strcpy(static_ip, json["ip"]); + strcpy(static_gw, json["gateway"]); + strcpy(static_sn, json["subnet"]); + //strcat(static_ip, json["ip"]); + //static_gw = json["gateway"]; + //static_sn = json["subnet"]; + Serial.println(static_ip); +/* Serial.println("converting ip"); + IPAddress ip = ipFromCharArray(static_ip); + Serial.println(ip);*/ + } else { + Serial.println("no custom ip in config"); + } + } else { + Serial.println("failed to load json config"); + } + } + } + } else { + Serial.println("failed to mount FS"); + } + //end read + Serial.println(static_ip); + Serial.println(blynk_token); + Serial.println(mqtt_server); + + + // The extra parameters to be configured (can be either global or just in the setup) + // After connecting, parameter.getValue() will get you the configured value + // id/name placeholder/prompt default length + WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, 40); + WiFiManagerParameter custom_mqtt_port("port", "mqtt port", mqtt_port, 5); + WiFiManagerParameter custom_blynk_token("blynk", "blynk token", blynk_token, 64); + + //WiFiManager + //Local intialization. Once its business is done, there is no need to keep it around + WiFiManager wifiManager; + + //set config save notify callback + wifiManager.setSaveConfigCallback(saveConfigCallback); + + //set static ip + IPAddress _ip,_gw,_sn; + _ip.fromString(static_ip); + _gw.fromString(static_gw); + _sn.fromString(static_sn); + + wifiManager.setSTAStaticIPConfig(_ip, _gw, _sn); + + //add all your parameters here + wifiManager.addParameter(&custom_mqtt_server); + wifiManager.addParameter(&custom_mqtt_port); + wifiManager.addParameter(&custom_blynk_token); + + //reset settings - for testing + //wifiManager.resetSettings(); + + //set minimu quality of signal so it ignores AP's under that quality + //defaults to 8% + wifiManager.setMinimumSignalQuality(); + + //sets timeout until configuration portal gets turned off + //useful to make it all retry or go to sleep + //in seconds + //wifiManager.setTimeout(120); + + //fetches ssid and pass and tries to connect + //if it does not connect it starts an access point with the specified name + //here "AutoConnectAP" + //and goes into a blocking loop awaiting configuration + if (!wifiManager.autoConnect("AutoConnectAP", "password")) { + Serial.println("failed to connect and hit timeout"); + delay(3000); + //reset and try again, or maybe put it to deep sleep + ESP.reset(); + delay(5000); + } + + //if you get here you have connected to the WiFi + Serial.println("connected...yeey :)"); + + //read updated parameters + strcpy(mqtt_server, custom_mqtt_server.getValue()); + strcpy(mqtt_port, custom_mqtt_port.getValue()); + strcpy(blynk_token, custom_blynk_token.getValue()); + //mqtt_port = custom_mqtt_port.getValue(); + //blynk_token = custom_blynk_token.getValue(); + + //save the custom parameters to FS + if (shouldSaveConfig) { + Serial.println("saving config"); + StaticJsonBuffer<200> jsonBuffer; + JsonObject& json = jsonBuffer.createObject(); + json["mqtt_server"] = mqtt_server; + json["mqtt_port"] = mqtt_port; + json["blynk_token"] = blynk_token; + + json["ip"] = WiFi.localIP().toString(); + json["gateway"] = WiFi.gatewayIP().toString(); + json["subnet"] = WiFi.subnetMask().toString(); + + File configFile = SPIFFS.open("/config.json", "w"); + if (!configFile) { + Serial.println("failed to open config file for writing"); + } + + json.prettyPrintTo(Serial); + json.printTo(configFile); + configFile.close(); + //end save + } + + Serial.println("local ip"); + Serial.println(WiFi.localIP()); + Serial.println(WiFi.gatewayIP()); + Serial.println(WiFi.subnetMask()); +} + +void loop() { + // put your main code here, to run repeatedly: + + +}