From b8c903534fb916d8a275fd3584ebede0ddf22057 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomislav=20Kopi=C4=87?= Date: Tue, 5 Nov 2024 12:18:36 +0100 Subject: [PATCH 01/12] Added netman library --- .vscode/settings.json | 8 ++ src/example_config.h | 4 - src/functions.h | 45 --------- src/main.cpp | 6 +- src/netman.h | 217 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 228 insertions(+), 52 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 src/netman.h diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..1f4c742 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "files.associations": { + "*.page-template": "vue", + "*.layout-template": "vue", + "*.vue": "vue", + "*.tcc": "cpp" + } +} \ No newline at end of file diff --git a/src/example_config.h b/src/example_config.h index 2875c4a..3b642ff 100644 --- a/src/example_config.h +++ b/src/example_config.h @@ -1,7 +1,3 @@ -// WiFi settings -#define WIFI_SSID "Your_SSID" -#define WIFI_PASSWORD "Your_Password" - // OctoPrint settings #define OCTOPRINT_HOST "your.octoprint.local" #define OCTOPRINT_PORT 9000 diff --git a/src/functions.h b/src/functions.h index c71bacf..48ab8c1 100644 --- a/src/functions.h +++ b/src/functions.h @@ -38,51 +38,6 @@ void initSystems() { display.display(); } -// Connect to WiFi -void connectToWifi() { - - display.clearDisplay(); - display.setCursor(0, 0); - display.println("Connecting to WiFi"); - display.display(); - - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - - int attemptCount = 0; - while (WiFi.status() != WL_CONNECTED && attemptCount < 20) { // Timeout after 20 attempts - delay(500); - display.print("."); - display.display(); - attemptCount++; - } - - // Check if connected - if (WiFi.status() == WL_CONNECTED) { - Serial.println("\nConnected to WiFi!"); - Serial.print("IP Address: "); - Serial.println(WiFi.localIP()); - - // Display connection success and IP address - display.clearDisplay(); - display.setCursor(0, 0); - display.print("WiFi Connected!"); - display.setCursor(0, 10); - display.print("IP: "); - display.print(WiFi.localIP()); - display.display(); - beep(800); - } else { - Serial.println("\nFailed to connect to WiFi."); - display.clearDisplay(); - display.setCursor(0, 0); - display.print("WiFi Connection"); - display.setCursor(0, 10); - display.print("Failed"); - display.display(); - } - delay(1000); -} - void commonButtonHandler() { unsigned long currentMillis = millis(); static unsigned long leftPressStart = 0; diff --git a/src/main.cpp b/src/main.cpp index d48fa26..c5ec626 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,14 +6,14 @@ #include "functions.h" #include "bitmaps.h" #include "octoprint.h" +#include "netman.h" void setup() { - initSystems(); + netman netman(display); playTune(1); - connectToWifi(); + netman.start(); displayOctoPrintVersion(display); - } void loop() { diff --git a/src/netman.h b/src/netman.h new file mode 100644 index 0000000..61570da --- /dev/null +++ b/src/netman.h @@ -0,0 +1,217 @@ +#include +#include +#include +#include +#include +#include +#include + +// Constants for the HTML pages and config file +static const String beginHtml = "AP Configure

"; +static const String endHtml = "
"; +static const String configFile = "/netman"; + +// Timeout for WiFi connection attempts +static const unsigned long connectionTimeout = 15000; // 15 seconds + +struct netman { +public: + netman(Adafruit_SSD1306& display); + netman(String ssid, String pass, bool hidden, Adafruit_SSD1306& display); + bool start(); + void reset(); + void addSsid(String ssid, String password); + void removeSsid(String ssid, String password); + +private: + Adafruit_SSD1306& display; + std::unique_ptr server; + std::map _ssids; + String _ssid, _pass; + bool _hidden; + + void init(String ssid, String pass, bool hidden); + bool tryConnectToSsid(const char* ssid, const char* pass); + bool tryConnect(); + void createAP(); + bool redirectToIp(); + void readConfig(); + void writeConfig(); + void handleRoot(); + void handleAdd(); + void handleRemove(); +}; + +// Initialization +void netman::init(String ssid, String pass, bool hidden) { + // Ensure password meets minimum length + if (pass != "" && pass.length() < 8) { + display.println("Password too short. Using default: '8characters'"); + pass = "8characters"; + } + + // Set default SSID if none provided + _ssid = ssid.isEmpty() ? "ESP" + String(ESP.getChipId()) : ssid; + _pass = pass; + _hidden = hidden; + + // Initialize LittleFS with error handling + if (!LittleFS.begin()) { + display.println("Failed to initialize filesystem."); + } +} + +// Constructors +netman::netman(Adafruit_SSD1306& display) : display(display) { + init("", "", false); +} + +netman::netman(String ssid, String pass, bool hidden, Adafruit_SSD1306& display) : display(display) { + init(ssid, pass, hidden); +} + +// Attempt to start and connect or create AP +bool netman::start() { + if (_pass == "8characters") { + display.println("Using default password due to length requirement."); + } + return tryConnect() || (createAP(), false); +} + +// Attempt connection to each saved SSID in order +bool netman::tryConnect() { + readConfig(); + for (auto const& item : _ssids) { + if (tryConnectToSsid(item.first.c_str(), item.second.c_str())) { + return true; + } + } + return false; +} + +// Attempt to connect to a specific SSID with timeout +bool netman::tryConnectToSsid(const char* ssid, const char* pass) { + WiFi.begin(ssid, pass); + unsigned long start = millis(); + + display.println("Connecting to " + String(ssid) + "..."); + while (millis() - start < connectionTimeout) { + delay(500); + if (WiFi.status() == WL_CONNECTED) { + display.println("Connected!"); + return true; + } + } + display.println("Connection failed."); + WiFi.disconnect(); + return false; +} + +// Setup Access Point with DNS and HTTP server +void netman::createAP() { + WiFi.softAPdisconnect(true); + WiFi.mode(WIFI_AP); + WiFi.softAP(_ssid.c_str(), _pass.c_str(), 1, _hidden); + + display.println("AP created with IP: " + WiFi.softAPIP().toString()); + + server.reset(new ESP8266WebServer(80)); + DNSServer dnsServer; + dnsServer.start(53, "*", WiFi.softAPIP()); + + server->on("/", std::bind(&netman::handleRoot, this)); + server->on("/add", std::bind(&netman::handleAdd, this)); + server->on("/remove", std::bind(&netman::handleRemove, this)); + + server->begin(); + display.println("HTTP server started"); + + while (true) { + dnsServer.processNextRequest(); + server->handleClient(); + delay(10); + } +} + +// Redirect to AP IP if not accessed directly +bool netman::redirectToIp() { + if (server->hostHeader() == WiFi.softAPIP().toString()) { + return false; + } + server->sendHeader("Location", "http://" + WiFi.softAPIP().toString(), true); + server->send(302, "text/plain", ""); + server->client().stop(); + return true; +} + +// Add SSID to config and save +void netman::addSsid(String ssid, String password) { + _ssids[ssid] = password; + writeConfig(); +} + +// Remove SSID from config +void netman::removeSsid(String ssid, String password) { + if (_ssids.count(ssid) && _ssids[ssid] == password) { + _ssids.erase(ssid); + writeConfig(); + } +} + +// Handle file-based config loading +void netman::readConfig() { + _ssids.clear(); + File file = LittleFS.open(configFile, "r"); + if (!file) { + display.println("No config file found."); + return; + } + + while (file.available()) { + String ssid = file.readStringUntil('\n'); + ssid.trim(); + String pass = file.readStringUntil('\n'); + pass.trim(); + _ssids[ssid] = pass; + } + file.close(); +} + +// Handle file-based config saving +void netman::writeConfig() { + File file = LittleFS.open(configFile, "w"); + for (const auto& item : _ssids) { + file.println(item.first); + file.println(item.second); + } + file.close(); +} + +// Reset configuration +void netman::reset() { + LittleFS.remove(configFile); + _ssids.clear(); +} + +// Web handlers for adding/removing SSIDs +void netman::handleRoot() { + if (redirectToIp()) return; + String result = beginHtml; + for (const auto& item : _ssids) { + result += "" + item.first + "-" + item.second + ""; + } + result += endHtml; + server->send(200, "text/html", result); +} + +void netman::handleAdd() { + server->send(200, "text/html", "The ESP will now reboot."); + addSsid(server->arg("ssid"), server->arg("pass")); + delay(500); + ESP.restart(); +} + +void netman::handleRemove() { + removeSsid(server->arg("ssid"), server->arg("pass")); + handleRoot(); +} From 56ed7e4b198efacc3d6180f1419f8abd23be0b76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomislav=20Kopi=C4=87?= Date: Tue, 5 Nov 2024 12:54:36 +0100 Subject: [PATCH 02/12] Basic functionality achived --- .vscode/settings.json | 3 ++- src/example_config.h | 4 ++-- src/netman.h | 39 +++++++++++++++++++++++++++++++-------- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 1f4c742..e2a0c98 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,6 +3,7 @@ "*.page-template": "vue", "*.layout-template": "vue", "*.vue": "vue", - "*.tcc": "cpp" + "*.tcc": "cpp", + "functional": "cpp" } } \ No newline at end of file diff --git a/src/example_config.h b/src/example_config.h index 3b642ff..27d815d 100644 --- a/src/example_config.h +++ b/src/example_config.h @@ -11,7 +11,7 @@ #define FRAMERATE 8 // Buttons and buzzer -#define PIN_BTN_L 12 // D6 +#define PIN_BTN_L 15 // D6 #define PIN_BTN_M 13 // D7 -#define PIN_BTN_R 15 // D8 +#define PIN_BTN_R 12 // D8 #define PIN_BUZZER 0 // D3 \ No newline at end of file diff --git a/src/netman.h b/src/netman.h index 61570da..e0dd843 100644 --- a/src/netman.h +++ b/src/netman.h @@ -46,18 +46,24 @@ private: void netman::init(String ssid, String pass, bool hidden) { // Ensure password meets minimum length if (pass != "" && pass.length() < 8) { - display.println("Password too short. Using default: '8characters'"); - pass = "8characters"; + display.clearDisplay(); + display.setCursor(0, 0); + display.println("Password too short"); + display.display(); + pass = "8characters"; } // Set default SSID if none provided - _ssid = ssid.isEmpty() ? "ESP" + String(ESP.getChipId()) : ssid; + _ssid = ssid.isEmpty() ? "SmartCube_" + String(ESP.getChipId()) : ssid; _pass = pass; _hidden = hidden; // Initialize LittleFS with error handling if (!LittleFS.begin()) { - display.println("Failed to initialize filesystem."); + display.clearDisplay(); + display.setCursor(0, 0); + display.println("FS init failed"); + display.display(); } } @@ -73,7 +79,11 @@ netman::netman(String ssid, String pass, bool hidden, Adafruit_SSD1306& display) // Attempt to start and connect or create AP bool netman::start() { if (_pass == "8characters") { - display.println("Using default password due to length requirement."); + display.clearDisplay(); + display.setCursor(0, 0); + display.println("Using default pass:"); + display.println("8characters"); + display.display(); } return tryConnect() || (createAP(), false); } @@ -81,6 +91,10 @@ bool netman::start() { // Attempt connection to each saved SSID in order bool netman::tryConnect() { readConfig(); + display.clearDisplay(); + display.setCursor(0, 0); + display.println("Connecting to wifi"); + display.display(); for (auto const& item : _ssids) { if (tryConnectToSsid(item.first.c_str(), item.second.c_str())) { return true; @@ -113,7 +127,14 @@ void netman::createAP() { WiFi.mode(WIFI_AP); WiFi.softAP(_ssid.c_str(), _pass.c_str(), 1, _hidden); - display.println("AP created with IP: " + WiFi.softAPIP().toString()); + display.clearDisplay(); + display.setCursor(0, 0); + display.println("AccessPoint created"); + display.println("SSID:"); + display.println(_ssid.c_str()); + display.println("IP:"); + display.println(WiFi.softAPIP().toString()); + display.display(); server.reset(new ESP8266WebServer(80)); DNSServer dnsServer; @@ -124,7 +145,6 @@ void netman::createAP() { server->on("/remove", std::bind(&netman::handleRemove, this)); server->begin(); - display.println("HTTP server started"); while (true) { dnsServer.processNextRequest(); @@ -163,7 +183,10 @@ void netman::readConfig() { _ssids.clear(); File file = LittleFS.open(configFile, "r"); if (!file) { - display.println("No config file found."); + display.clearDisplay(); + display.setCursor(0, 0); + display.println("Config not found"); + display.display(); return; } From 20a6714bef5f95f204834279d86c6c0d918f225a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomislav=20Kopi=C4=87?= Date: Tue, 5 Nov 2024 13:05:31 +0100 Subject: [PATCH 03/12] Add flair --- src/netman.h | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/netman.h b/src/netman.h index e0dd843..4778398 100644 --- a/src/netman.h +++ b/src/netman.h @@ -7,7 +7,7 @@ #include // Constants for the HTML pages and config file -static const String beginHtml = "AP Configure

"; +static const String beginHtml = "SmartCube Configure

Configure AP


"; static const String endHtml = "
"; static const String configFile = "/netman"; @@ -104,19 +104,48 @@ bool netman::tryConnect() { } // Attempt to connect to a specific SSID with timeout +// Attempt to connect to a specific SSID with timeout and dot animation bool netman::tryConnectToSsid(const char* ssid, const char* pass) { WiFi.begin(ssid, pass); unsigned long start = millis(); - display.println("Connecting to " + String(ssid) + "..."); + // Clear display and set initial message + display.clearDisplay(); + display.setCursor(0, 0); + display.println("Connecting to SSID:"); + display.println(String(ssid)); + display.display(); + + int dotCount = 0; while (millis() - start < connectionTimeout) { delay(500); + + // Check WiFi connection status if (WiFi.status() == WL_CONNECTED) { + // Success message + display.clearDisplay(); + display.setCursor(0, 0); display.println("Connected!"); + display.display(); return true; } + + // Animate by adding dots up to three, then reset + display.setCursor(0, 20); + display.print("Connecting"); + for (int i = 0; i < dotCount; i++) { + display.print("."); + } + display.display(); + + dotCount = (dotCount + 1) % 4; // Cycle dot count from 0 to 3 } + + // Connection failed + display.clearDisplay(); + display.setCursor(0, 0); display.println("Connection failed."); + display.display(); WiFi.disconnect(); return false; } From f835aa01223a2679a01ff5a6687c84158ec85e6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomislav=20Kopi=C4=87?= Date: Tue, 5 Nov 2024 13:13:32 +0100 Subject: [PATCH 04/12] Fix animation --- src/netman.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/netman.h b/src/netman.h index 4778398..3b1015f 100644 --- a/src/netman.h +++ b/src/netman.h @@ -103,12 +103,11 @@ bool netman::tryConnect() { return false; } -// Attempt to connect to a specific SSID with timeout -// Attempt to connect to a specific SSID with timeout and dot animation +// Attempt to connect to a specific SSID with timeout, dot animation, and IP display bool netman::tryConnectToSsid(const char* ssid, const char* pass) { WiFi.begin(ssid, pass); unsigned long start = millis(); - + // Clear display and set initial message display.clearDisplay(); display.setCursor(0, 0); @@ -122,23 +121,24 @@ bool netman::tryConnectToSsid(const char* ssid, const char* pass) { // Check WiFi connection status if (WiFi.status() == WL_CONNECTED) { - // Success message + // Success message with IP address display.clearDisplay(); display.setCursor(0, 0); display.println("Connected!"); + display.setCursor(0, 10); + display.print("IP: "); + display.println(WiFi.localIP()); display.display(); return true; } // Animate by adding dots up to three, then reset display.setCursor(0, 20); - display.print("Connecting"); for (int i = 0; i < dotCount; i++) { display.print("."); } display.display(); - - dotCount = (dotCount + 1) % 4; // Cycle dot count from 0 to 3 + dotCount = (dotCount + 1); } // Connection failed From 1c6d4eaabad6c235e7a5586156e214ebf3e9c091 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomislav=20Kopi=C4=87?= Date: Tue, 5 Nov 2024 13:33:40 +0100 Subject: [PATCH 05/12] Change AP SSID generator --- src/netman.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/netman.h b/src/netman.h index 3b1015f..a859671 100644 --- a/src/netman.h +++ b/src/netman.h @@ -53,11 +53,16 @@ void netman::init(String ssid, String pass, bool hidden) { pass = "8characters"; } + // Get the last 4 characters of the MAC address + String macAddress = WiFi.macAddress(); + String macSuffix = macAddress.substring(macAddress.length() - 5).replace(":", ""); + // Set default SSID if none provided - _ssid = ssid.isEmpty() ? "SmartCube_" + String(ESP.getChipId()) : ssid; + _ssid = ssid.isEmpty() ? "SmartCube_" + macSuffix : ssid; _pass = pass; _hidden = hidden; + // Initialize LittleFS with error handling if (!LittleFS.begin()) { display.clearDisplay(); @@ -159,8 +164,12 @@ void netman::createAP() { display.clearDisplay(); display.setCursor(0, 0); display.println("AccessPoint created"); + display.setCursor(0, 12); display.println("SSID:"); + display.setTextSize(2); display.println(_ssid.c_str()); + display.setTextSize(1); + display.setCursor(0, 32); display.println("IP:"); display.println(WiFi.softAPIP().toString()); display.display(); From 9c25cb47cd9f82d37331af37e0bff7dba9023f73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomislav=20Kopi=C4=87?= Date: Tue, 5 Nov 2024 18:26:24 +0100 Subject: [PATCH 06/12] Fix MAC address formating --- src/netman.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/netman.h b/src/netman.h index a859671..7fa01fb 100644 --- a/src/netman.h +++ b/src/netman.h @@ -55,7 +55,8 @@ void netman::init(String ssid, String pass, bool hidden) { // Get the last 4 characters of the MAC address String macAddress = WiFi.macAddress(); - String macSuffix = macAddress.substring(macAddress.length() - 5).replace(":", ""); + String macSuffix = macAddress.substring(macAddress.length() - 5); + macSuffix.replace(":", ""); // Set default SSID if none provided _ssid = ssid.isEmpty() ? "SmartCube_" + macSuffix : ssid; From 0d5265d1ad73d935be8f6897410c9fd071c9d016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomislav=20Kopi=C4=87?= Date: Tue, 5 Nov 2024 18:46:51 +0100 Subject: [PATCH 07/12] Tune up screens --- src/netman.h | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/netman.h b/src/netman.h index 7fa01fb..f14a75c 100644 --- a/src/netman.h +++ b/src/netman.h @@ -97,10 +97,6 @@ bool netman::start() { // Attempt connection to each saved SSID in order bool netman::tryConnect() { readConfig(); - display.clearDisplay(); - display.setCursor(0, 0); - display.println("Connecting to wifi"); - display.display(); for (auto const& item : _ssids) { if (tryConnectToSsid(item.first.c_str(), item.second.c_str())) { return true; @@ -117,7 +113,8 @@ bool netman::tryConnectToSsid(const char* ssid, const char* pass) { // Clear display and set initial message display.clearDisplay(); display.setCursor(0, 0); - display.println("Connecting to SSID:"); + display.println("Connecting to WiFi:"); + display.setCursor(0, 11); display.println(String(ssid)); display.display(); @@ -131,10 +128,11 @@ bool netman::tryConnectToSsid(const char* ssid, const char* pass) { display.clearDisplay(); display.setCursor(0, 0); display.println("Connected!"); - display.setCursor(0, 10); + display.setCursor(0, 12); display.print("IP: "); display.println(WiFi.localIP()); display.display(); + delay(500); return true; } @@ -165,13 +163,16 @@ void netman::createAP() { display.clearDisplay(); display.setCursor(0, 0); display.println("AccessPoint created"); - display.setCursor(0, 12); + display.setCursor(0, 14); display.println("SSID:"); - display.setTextSize(2); + display.setCursor(0, 24); + display.setTextSize(1); display.println(_ssid.c_str()); display.setTextSize(1); - display.setCursor(0, 32); - display.println("IP:"); + display.setCursor(0, 40); + display.println("Config portal:"); + display.setCursor(0, 50); + display.print("http://"); display.println(WiFi.softAPIP().toString()); display.display(); From d1b2e6d3656a17d5a43d7ef9fde9c713ac544ad5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomislav=20Kopi=C4=87?= Date: Tue, 5 Nov 2024 18:49:38 +0100 Subject: [PATCH 08/12] Fix comment --- src/netman.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/netman.h b/src/netman.h index f14a75c..4c767e0 100644 --- a/src/netman.h +++ b/src/netman.h @@ -136,7 +136,7 @@ bool netman::tryConnectToSsid(const char* ssid, const char* pass) { return true; } - // Animate by adding dots up to three, then reset + // Animate by adding dots display.setCursor(0, 20); for (int i = 0; i < dotCount; i++) { display.print("."); From 3d43fa7a84805a718fb54fc573d01835cb309d36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomislav=20Kopi=C4=87?= Date: Tue, 5 Nov 2024 19:33:37 +0100 Subject: [PATCH 09/12] Add scaning wifi, make config page responsive --- src/netman.h | 68 ++++++++++++++++++++++++++++++++++++++++++++++--- src/octoprint.h | 21 +++++++-------- 2 files changed, 76 insertions(+), 13 deletions(-) diff --git a/src/netman.h b/src/netman.h index 4c767e0..dc6f336 100644 --- a/src/netman.h +++ b/src/netman.h @@ -7,7 +7,7 @@ #include // Constants for the HTML pages and config file -static const String beginHtml = "SmartCube Configure

Configure AP


"; +static const String beginHtml = "SmartCube Configure

Configure AP


"; static const String endHtml = "
"; static const String configFile = "/netman"; @@ -40,6 +40,7 @@ private: void handleRoot(); void handleAdd(); void handleRemove(); + void handleSelect(); }; // Initialization @@ -183,6 +184,7 @@ void netman::createAP() { server->on("/", std::bind(&netman::handleRoot, this)); server->on("/add", std::bind(&netman::handleAdd, this)); server->on("/remove", std::bind(&netman::handleRemove, this)); + server->on("/select", std::bind(&netman::handleSelect, this)); server->begin(); @@ -204,10 +206,20 @@ bool netman::redirectToIp() { return true; } -// Add SSID to config and save +// Modify the addSsid function to take parameters from the `select` page void netman::addSsid(String ssid, String password) { _ssids[ssid] = password; writeConfig(); + + // Attempt to connect to the selected network + if (tryConnectToSsid(ssid.c_str(), password.c_str())) { + // Redirect to the main page on success + server->sendHeader("Location", "/", true); + server->send(302, "text/plain", ""); + } else { + // Show error message if connection failed + server->send(200, "text/html", "

Connection failed. Please try again.

"); + } } // Remove SSID from config @@ -256,13 +268,47 @@ void netman::reset() { _ssids.clear(); } -// Web handlers for adding/removing SSIDs +String urlEncode(const String &str) { + String encoded = ""; + char c; + for (size_t i = 0; i < str.length(); i++) { + c = str.charAt(i); + if (isalnum(c)) { + encoded += c; + } else { + encoded += '%'; + char buf[3]; + snprintf(buf, sizeof(buf), "%02X", c); + encoded += buf; + } + } + return encoded; +} + void netman::handleRoot() { if (redirectToIp()) return; + + // Scan for available networks + int n = WiFi.scanNetworks(); String result = beginHtml; + + // Add stored SSIDs to the page + result += "

Saved Networks

"; for (const auto& item : _ssids) { result += "" + item.first + "-" + item.second + ""; } + + // Display available WiFi networks + result += "

Available Networks

"; + for (int i = 0; i < n; i++) { + // Get SSID and signal strength + String ssid = WiFi.SSID(i); + int rssi = WiFi.RSSI(i); + bool openNetwork = (WiFi.encryptionType(i) == ENC_TYPE_NONE); + + // Show network with button to select + result += ""; + } result += endHtml; server->send(200, "text/html", result); } @@ -278,3 +324,19 @@ void netman::handleRemove() { removeSsid(server->arg("ssid"), server->arg("pass")); handleRoot(); } + +// Add SSID to config and save +void netman::handleSelect() { + String ssid = server->arg("ssid"); + + // Display prompt for password if network is secured + String selectPage = "Connect to " + ssid + ""; + selectPage += "

Connect to " + ssid + "

"; + selectPage += ""; + selectPage += ""; + selectPage += "

"; + selectPage += ""; + selectPage += ""; + + server->send(200, "text/html", selectPage); +} \ No newline at end of file diff --git a/src/octoprint.h b/src/octoprint.h index 45c97dc..a0d23c9 100644 --- a/src/octoprint.h +++ b/src/octoprint.h @@ -138,19 +138,20 @@ bool fetchPrintingStatus(Adafruit_SSD1306& display) { display.fillRect(0, 26, displayWidth, 11, BLACK); // Check if it’s time to scroll based on the delay - if (millis() - lastScrollTime > scrollDelay) { - // Update scroll position based on the current direction - scrollPos += scrollDirection; - lastScrollTime = millis(); + if(fileNameWidth > 22) { + if (millis() - lastScrollTime > scrollDelay) { + // Update scroll position based on the current direction + scrollPos += scrollDirection; + lastScrollTime = millis(); - // Reverse direction if the text reaches either edge - if (scrollPos > 0) { // Reached the left edge - scrollDirection = -1; // Start moving left - } else if (scrollPos < -fileNameWidth + displayWidth) { // Reached the right edge - scrollDirection = 1; // Start moving right + // Reverse direction if the text reaches either edge + if (scrollPos > 0) { // Reached the left edge + scrollDirection = -1; // Start moving left + } else if (scrollPos < -fileNameWidth + displayWidth) { // Reached the right edge + scrollDirection = 1; // Start moving right + } } } - // Draw the file name with current scroll position display.setCursor(scrollPos, 27); display.print(fileName); From fd3c54d5170a703eea2f91797a9e720b69b69b9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomislav=20Kopi=C4=87?= Date: Tue, 5 Nov 2024 19:37:32 +0100 Subject: [PATCH 10/12] Make password entry page pretty --- src/netman.h | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/netman.h b/src/netman.h index dc6f336..d8c131a 100644 --- a/src/netman.h +++ b/src/netman.h @@ -328,15 +328,6 @@ void netman::handleRemove() { // Add SSID to config and save void netman::handleSelect() { String ssid = server->arg("ssid"); - - // Display prompt for password if network is secured - String selectPage = "Connect to " + ssid + ""; - selectPage += "

Connect to " + ssid + "

"; - selectPage += "
"; - selectPage += ""; - selectPage += "

"; - selectPage += ""; - selectPage += ""; - + String selectPage = "Connect to " + ssid + "

Connect to " + ssid + "

"; server->send(200, "text/html", selectPage); } \ No newline at end of file From 3f20df75711fb8525698c3bc28c7e58d925360e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomislav=20Kopi=C4=87?= Date: Tue, 5 Nov 2024 19:39:55 +0100 Subject: [PATCH 11/12] Fix ping pong scroll logic --- src/octoprint.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/octoprint.h b/src/octoprint.h index a0d23c9..77d5290 100644 --- a/src/octoprint.h +++ b/src/octoprint.h @@ -138,7 +138,7 @@ bool fetchPrintingStatus(Adafruit_SSD1306& display) { display.fillRect(0, 26, displayWidth, 11, BLACK); // Check if it’s time to scroll based on the delay - if(fileNameWidth > 22) { + if(fileNameWidth > displayWidth) { if (millis() - lastScrollTime > scrollDelay) { // Update scroll position based on the current direction scrollPos += scrollDirection; From 877d2b1207ee249c9fa0871fbbe5b0ec22893eed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomislav=20Kopi=C4=87?= Date: Tue, 5 Nov 2024 20:41:10 +0100 Subject: [PATCH 12/12] Fix include order --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index c5ec626..06e6d55 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,10 +3,10 @@ #include #include #include +#include "netman.h" #include "functions.h" #include "bitmaps.h" #include "octoprint.h" -#include "netman.h" void setup() { initSystems();
" + (openNetwork ? "(Open)" : "(Secured)") + "" + String(rssi) + " dBm