"; // {q} = HTTP_ITEM_QI, {r} = HTTP_ITEM_QP
+// const char HTTP_ITEM[] = ""; // test all tokens
+
+const char HTTP_FORM_START[] = "";
+const char HTTP_FORM_LABEL[] = "{t} ";
+const char HTTP_FORM_PARAM_HEAD[] = " ";
+const char HTTP_FORM_PARAM[] = " \n"; // do not remove newline!
+
+const char HTTP_SCAN_LINK[] = " ";
+const char HTTP_REBOOT_LINK[] = " ";
+
+const char HTTP_SAVED[] = "Saving Credentials Trying to connect ESP to network. If it fails reconnect to AP to try again
";
+const char HTTP_PARAMSAVED[] = "Saved
";
+const char HTTP_END[] = "";
+const char HTTP_ERASEBTN[] = " ";
+const char HTTP_UPDATEBTN[] = " ";
+const char HTTP_BACKBTN[] = " ";
+
+const char HTTP_STATUS_ON[] = "Connected to {v}with IP {i}
";
+const char HTTP_STATUS_OFF[] = "Not connected to {v}{r}
"; // {c=class} {v=ssid} {r=status_off}
+const char HTTP_STATUS_OFFPW[] = " Authentication failure"; // STATION_WRONG_PASSWORD, no eps32
+const char HTTP_STATUS_OFFNOAP[] = " AP not found"; // WL_NO_SSID_AVAIL
+const char HTTP_STATUS_OFFFAIL[] = " Could not connect"; // WL_CONNECT_FAILED
+const char HTTP_STATUS_NONE[] = "No AP set
";
+const char HTTP_BR[] = " ";
+
+const char HTTP_UPDATE_FAIL[] = "Update failed! Reboot device and try again
";
+const char HTTP_UPDATE_SUCCESS[] = "Update successful. Device rebooting now...
";
+
+const char HTTP_INFO_esphead[] = "esp32 ";
+const char HTTP_INFO_chiprev[] = "Chip rev {1} ";
+const char HTTP_INFO_lastreset[] = "Last reset reason CPU0: {1} CPU1: {2} ";
+const char HTTP_INFO_aphost[] = "Access point hostname {1} ";
+const char HTTP_INFO_psrsize[] = "PSRAM Size {1} bytes ";
+const char HTTP_INFO_temp[] = "Temperature {1} C° / {2} F° ";
+const char HTTP_INFO_hall[] = "Hall {1} ";
+
+const char HTTP_INFO_memsmeter[] = " ";
+const char HTTP_INFO_memsketch[] = "Memory - Sketch size Used / Total bytes {1} / {2}";
+const char HTTP_INFO_freeheap[] = " Memory - Free heap {1} bytes available ";
+const char HTTP_INFO_wifihead[] = "WiFi ";
+const char HTTP_INFO_uptime[] = "Uptime {1} mins {2} secs ";
+const char HTTP_INFO_chipid[] = "Chip ID {1} ";
+const char HTTP_INFO_idesize[] = "Flash size {1} bytes ";
+const char HTTP_INFO_sdkver[] = "SDK version {1} ";
+const char HTTP_INFO_cpufreq[] = "CPU frequency {1}MHz ";
+const char HTTP_INFO_apip[] = "Access point IP {1} ";
+const char HTTP_INFO_apmac[] = "Access point MAC {1} ";
+const char HTTP_INFO_apssid[] = "Access point SSID {1} ";
+const char HTTP_INFO_apbssid[] = "BSSID {1} ";
+const char HTTP_INFO_stassid[] = "Station SSID {1} ";
+const char HTTP_INFO_staip[] = "Station IP {1} ";
+const char HTTP_INFO_stagw[] = "Station gateway {1} ";
+const char HTTP_INFO_stasub[] = "Station subnet {1} ";
+const char HTTP_INFO_dnss[] = "DNS Server {1} ";
+const char HTTP_INFO_host[] = "Hostname {1} ";
+const char HTTP_INFO_stamac[] = "Station MAC {1} ";
+const char HTTP_INFO_conx[] = "Connected {1} ";
+const char HTTP_INFO_autoconx[] = "Autoconnect {1} ";
+
+const char HTTP_INFO_aboutarduino[] = "Arduino {1} ";
+const char HTTP_INFO_aboutsdk[] = "ESP-SDK/IDF {1} ";
+const char HTTP_INFO_aboutdate[] = "Build date {1} ";
+
+const char WIFI_PAGE_TITLE[] = "WiFi Setup ";
+const char S_y[] = "Yes";
+const char S_n[] = "No";
+const char S_enable[] = "Enabled";
+const char S_disable[] = "Disabled";
+const char S_GET[] = "GET";
+const char S_POST[] = "POST";
+const char S_NA[] = "Unknown";
+const char S_passph[] = "********";
+const char S_titlewifisaved[] = "Credentials saved";
+const char S_titlewifisettings[] = "Settings saved";
+const char S_titlewifi[] = "Config ESP";
+const char S_titleinfo[] = "Info";
+const char S_titleparam[] = "Setup";
+const char S_titleparamsaved[] = "Setup saved";
+const char S_titleexit[] = "Exit";
+const char S_titlereset[] = "Reset";
+const char S_titleerase[] = "Erase";
+const char S_titleclose[] = "Close";
+const char S_options[] = "options";
+const char S_nonetworks[] = "No networks found. Refresh to scan again.";
+const char S_staticip[] = "Static IP";
+const char S_staticgw[] = "Static gateway";
+const char S_staticdns[] = "Static DNS";
+const char S_subnet[] = "Subnet";
+const char S_exiting[] = "Exiting";
+const char S_resetting[] = "Module will reset in a few seconds.";
+const char S_closing[] = "You can close the page, portal will continue to run";
+const char S_error[] = "An error occured";
+const char S_notfound[] = "File not found\n\n";
+const char S_uri[] = "URI: ";
+const char S_method[] = "\nMethod: ";
+const char S_args[] = "\nArguments: ";
+const char S_parampre[] = "param_";
+
+// debug strings
+const char D_HR[] = "--------------------";
+
+const char S_ssidpre[] = "ESP32";
+
+const char WM_VERSION_STR[] = "v2.0.15-rc.1";
+
+static const char _wifi_token[] = "wifi";
+static const char _wifinoscan_token[] = "wifinoscan";
+static const char _info_token[] = "info";
+static const char _param_token[] = "param";
+static const char _close_token[] = "close";
+static const char _restart_token[] = "restart";
+static const char _exit_token[] = "exit";
+static const char _erase_token[] = "erase";
+static const char _update_token[] = "update";
+static const char _sep_token[] = "sep";
+static const char _custom_token[] = "custom";
+static PGM_P _menutokens[] = {_wifi_token, _wifinoscan_token, _info_token, _param_token, _close_token, _restart_token,
+ _exit_token, _erase_token, _update_token, _sep_token, _custom_token};
+const uint8_t _nummenutokens = (sizeof(_menutokens) / sizeof(PGM_P));
+
+const char R_root[] = "/";
+const char R_wifi[] = "/wifi";
+const char R_wifinoscan[] = "/0wifi";
+const char R_wifisave[] = "/send_settings";
+const char R_info[] = "/info";
+const char R_param[] = "/param";
+const char R_paramsave[] = "/paramsave";
+const char R_restart[] = "/restart";
+const char R_exit[] = "/exit";
+const char R_close[] = "/close";
+const char R_erase[] = "/erase";
+const char R_status[] = "/status";
+const char R_update[] = "/update";
+const char R_updatedone[] = "/u";
+
+// Strings
+const char S_ip[] = "ip";
+const char S_gw[] = "gw";
+const char S_sn[] = "sn";
+const char S_dns[] = "dns";
+
+// Tokens
+//@todo consolidate and reduce
+const char T_ss[] = "{"; // token start sentinel
+const char T_es[] = "}"; // token end sentinel
+const char T_1[] = "{1}"; // @token 1
+const char T_2[] = "{2}"; // @token 2
+const char T_3[] = "{3}"; // @token 2
+const char T_v[] = "{v}"; // @token v
+const char T_V[] = "{V}"; // @token v
+const char T_I[] = "{I}"; // @token I
+const char T_i[] = "{i}"; // @token i
+const char T_n[] = "{n}"; // @token n
+const char T_p[] = "{p}"; // @token p
+const char T_t[] = "{t}"; // @token t
+const char T_l[] = "{l}"; // @token l
+const char T_c[] = "{c}"; // @token c
+const char T_e[] = "{e}"; // @token e
+const char T_q[] = "{q}"; // @token q
+const char T_r[] = "{r}"; // @token r
+const char T_R[] = "{R}"; // @token R
+const char T_h[] = "{h}"; // @token h
+
+// http
+const char HTTP_HEAD_CL[] = "Content-Length";
+const char HTTP_HEAD_CT[] = "text/html";
+const char HTTP_HEAD_CT2[] = "text/plain";
+const char HTTP_HEAD_CORS[] = "Access-Control-Allow-Origin";
+const char HTTP_HEAD_CORS_ALLOW_ALL[] = "*";
+
+const char* const WIFI_STA_STATUS[]{
+ "WL_IDLE_STATUS", // 0 STATION_IDLE
+ "WL_NO_SSID_AVAIL", // 1 STATION_NO_AP_FOUND
+ "WL_SCAN_COMPLETED", // 2
+ "WL_CONNECTED", // 3 STATION_GOT_IP
+ "WL_CONNECT_FAILED", // 4 STATION_CONNECT_FAIL, STATION_WRONG_PASSWORD(NI)
+ "WL_CONNECTION_LOST", // 5
+ "WL_DISCONNECTED", // 6
+ "WL_STATION_WRONG_PASSWORD" // 7 KLUDGE
+};
+
+const char* const AUTH_MODE_NAMES[]{"OPEN", "WEP", "WPA_PSK", "WPA2_PSK", "WPA_WPA2_PSK", "WPA2_ENTERPRISE", "MAX"};
+
+const char* const WIFI_MODES[] = {"NULL", "STA", "AP", "STA+AP"};
\ No newline at end of file
diff --git a/include/HTTP_Server_Basic.h b/include/HTTP_Server_Basic.h
index b38628fd..72416382 100644
--- a/include/HTTP_Server_Basic.h
+++ b/include/HTTP_Server_Basic.h
@@ -13,9 +13,11 @@
class HTTP_Server {
private:
- public:
- bool internetConnection;
+ String processWiFiHTML();
+ public:
+ bool internetConnection = false;
+ bool isServing = false;
void start();
void stop();
static void handleLittleFSFile();
@@ -23,9 +25,7 @@ class HTTP_Server {
static void settingsProcessor();
static void handleHrSlider();
static void FirmwareUpdate();
-
static void webClientUpdate(void *pvParameters);
-
HTTP_Server() { internetConnection = false; }
};
@@ -38,9 +38,13 @@ void telegramUpdate(void *pvParameters);
#define SEND_TO_TELEGRAM(message) (void)message
#endif
-// wifi Function
void startWifi();
void stopWifi();
-
+String getScanItemOut();
+String encryptionTypeStr(uint8_t authmode);
+bool WiFi_scanNetworks();
+String getHTTPHead();
+int getRSSIasQuality(int RSSI);
+String htmlEntities(String str, bool whitespace = false);
extern HTTP_Server httpServer;
diff --git a/include/WebsocketAppender.h b/include/WebsocketAppender.h
index c893ba56..653302d0 100644
--- a/include/WebsocketAppender.h
+++ b/include/WebsocketAppender.h
@@ -9,6 +9,7 @@
#include
#include "LogAppender.h"
+#include "main.h"
using namespace websockets;
diff --git a/include/settings.h b/include/settings.h
index 1b0c5874..a9088a92 100644
--- a/include/settings.h
+++ b/include/settings.h
@@ -213,7 +213,7 @@
#define MAX_RECONNECT_TRIES 3
// loop speed for the SmartSpin2k BLE communications
-#define BLE_NOTIFY_DELAY 503
+#define BLE_NOTIFY_DELAY 503
// loop speed for the SmartSpin2k BLE Client reconnect
#define BLE_CLIENT_DELAY 101
@@ -273,7 +273,7 @@
#define NORMAL_CAD 90
// Temperature of the ESP32 at which to start reducing the power output of the stepper motor driver.
-#define THROTTLE_TEMP 85
+#define THROTTLE_TEMP 100
// Size of the Aux Serial Buffer for Peloton
#define AUX_BUF_SIZE 10
diff --git a/platformio.ini b/platformio.ini
index cb7f04c9..0fadb375 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -13,7 +13,7 @@ default_envs = release
[esp32doit]
lib_ldf_mode = chain
lib_compat_mode = strict
-platform = espressif32 @ 6.0.1
+platform = espressif32 @ 6.4.0
board = esp32doit-devkit-v1
framework = arduino
board_build.partitions = min_spiffs.csv
@@ -26,7 +26,7 @@ build_flags =
!python build_date_macro.py
-D CONFIG_BT_NIMBLE_MAX_CONNECTIONS=6
-D CONFIG_MDNS_STRICT_MODE=1
- -D CORE_DEBUG_LEVEL=1
+ -D CORE_DEBUG_LEVEL=2
-D ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=3500
lib_deps =
https://github.com/h2zero/NimBLE-Arduino/archive/refs/tags/1.4.0.zip
diff --git a/src/BLE_Client.cpp b/src/BLE_Client.cpp
index f228931b..8657218d 100644
--- a/src/BLE_Client.cpp
+++ b/src/BLE_Client.cpp
@@ -58,16 +58,30 @@ static void onNotify(BLERemoteCharacteristic *pBLERemoteCharacteristic, uint8_t
}
}
-// BLE Client loop task
+// BLE Client loop task. Manages connections to BLE servers.
void bleClientTask(void *pvParameters) {
+ static unsigned long scanCacheTimer = millis();
for (;;) {
- vTaskDelay(BLE_CLIENT_DELAY / portTICK_PERIOD_MS); // Delay a second between loops.
+ if (httpServer.isServing) { // Scan slower if HTTP Server is working.
+ vTaskDelay((BLE_NOTIFY_DELAY * 3) / portTICK_PERIOD_MS);
+ }
+ vTaskDelay(BLE_CLIENT_DELAY / portTICK_PERIOD_MS);
+
+ NimBLEScan *scan = NimBLEDevice::getScan();
+ if (scan) {
+ while (scan->isScanning()) { // wait for current scan to finish
+ vTaskDelay(BLE_CLIENT_DELAY / portTICK_PERIOD_MS);
+ Serial.print(".");
+ }
+ }
+
+ if ((millis() - scanCacheTimer) > 1200000) { // Clear the scan cache every 120 seconds
+ scanCacheTimer = millis();
+ SS2K_LOG(BLE_CLIENT_LOG_TAG, "Clearing BLE Scan Cache.");
+ scan->clearDuplicateCache();
+ scan->clearResults();
+ }
spinBLEClient.checkBLEReconnect();
- // if (spinBLEClient.doScan && (spinBLEClient.scanRetries > 0) && !NimBLEDevice::getScan()->isScanning()) {
- // spinBLEClient.scanRetries--;
- // SS2K_LOG(BLE_CLIENT_LOG_TAG, "Initiating Scan from Client Task:");
- // spinBLEClient.scanProcess();
- // }
#ifdef DEBUG_STACK
Serial.printf("BLEClient: %d \n", uxTaskGetStackHighWaterMark(BLEClientTask));
#endif // DEBUG_STACK
@@ -75,7 +89,6 @@ void bleClientTask(void *pvParameters) {
if (spinBLEClient.myBLEDevices[x].doConnect == true) {
if (spinBLEClient.connectToServer()) {
SS2K_LOG(BLE_CLIENT_LOG_TAG, "We are now connected to the BLE Server.");
- // vTaskDelay(5000 / portTICK_PERIOD_MS);
} else {
}
}
@@ -182,7 +195,9 @@ bool SpinBLEClient::connectToServer() {
spinBLEClient.resetDevices(pClient);
pClient->deleteServices();
pClient->disconnect();
- NimBLEDevice::getScan()->erase(pClient->getPeerAddress());
+ if (NimBLEDevice::getScan()) {
+ NimBLEDevice::getScan()->erase(pClient->getPeerAddress());
+ }
NimBLEDevice::deleteClient(pClient);
}
return false;
@@ -447,7 +462,7 @@ void SpinBLEClient::scanProcess(int duration) {
pBLEScan->setDuplicateFilter(true);
pBLEScan->setActiveScan(true);
BLEScanResults foundDevices = pBLEScan->start(duration, true);
- this->dontBlockScan = false;
+ // this->dontBlockScan = false;
// Load the scan into a Json String
int count = foundDevices.getCount();
diff --git a/src/BLE_Common.cpp b/src/BLE_Common.cpp
index 218ab074..f93778f9 100644
--- a/src/BLE_Common.cpp
+++ b/src/BLE_Common.cpp
@@ -21,9 +21,9 @@ TaskHandle_t BLECommunicationTask;
void BLECommunications(void *pvParameters) {
for (;;) {
- if (!spinBLEClient.dontBlockScan) {
- NimBLEDevice::getScan()->stop(); // stop routine scans
- }
+ // if (!spinBLEClient.dontBlockScan) {
+ // NimBLEDevice::getScan()->stop(); // stop routine scans
+ //}
// **********************************Client***************************************
for (size_t x = 0; x < NUM_BLE_DEVICES; x++) { // loop through discovered devices
if (spinBLEClient.myBLEDevices[x].connectedClientID != BLE_HS_CONN_HANDLE_NONE) {
@@ -138,6 +138,9 @@ void BLECommunications(void *pvParameters) {
} else {
digitalWrite(LED_PIN, HIGH);
}
+ if (httpServer.isServing) { // slow the BLE communications for faster web tasks.
+ vTaskDelay((BLE_NOTIFY_DELAY) / portTICK_PERIOD_MS);
+ }
vTaskDelay((BLE_NOTIFY_DELAY) / portTICK_PERIOD_MS);
#ifdef DEBUG_STACK
Serial.printf("BLEComm: %d \n", uxTaskGetStackHighWaterMark(BLECommunicationTask));
diff --git a/src/HTTP_Server_Basic.cpp b/src/HTTP_Server_Basic.cpp
index 8210ef09..d8df536a 100644
--- a/src/HTTP_Server_Basic.cpp
+++ b/src/HTTP_Server_Basic.cpp
@@ -34,6 +34,11 @@ HTTP_Server httpServer;
WiFiClientSecure client;
WebServer server(80);
+// WiFi Scanner
+int _numNetworks = 0;
+int _minimumQuality = -1;
+bool haveScan = false;
+
#ifdef USE_TELEGRAM
#include
TaskHandle_t telegramTask;
@@ -148,9 +153,7 @@ void HTTP_Server::start() {
String response =
"Scanning for BLE Devices. Please wait "
"15 seconds.";
- // spinBLEClient.resetDevices();
- spinBLEClient.dontBlockScan = true;
+ myIP.toString() + "/bluetoothscanner.html';\",100);";
spinBLEClient.scanProcess(DEFAULT_SCAN_DURATION);
server.send(200, "text/html", response);
});
@@ -291,7 +294,17 @@ void HTTP_Server::start() {
server.on("/login", HTTP_GET, []() {
server.sendHeader("Connection", "close");
- server.send(200, "text/html", OTALoginIndex);
+ String page = FPSTR(OTALOGININDEX);
+ page += FPSTR(HTTP_STYLE);
+ server.send(200, "text/html", page);
+ });
+
+ server.on("/wifi", []() {
+ if (!server.arg("refresh").isEmpty()) {
+ WiFi_scanNetworks();
+ }
+ server.sendHeader("Connection", "close");
+ server.send(200, "text/html", httpServer.processWiFiHTML());
});
server.on("/OTAIndex", HTTP_GET, []() {
@@ -384,7 +397,7 @@ void HTTP_Server::start() {
"webClientUpdate", /* name of task. */
HTTP_STACK + (DEBUG_LOG_BUFFER_SIZE * 2), /* Stack size of task Used to be 3000*/
NULL, /* parameter of the task */
- 10, /* priority of the task */
+ 4, /* priority of the task */
&webClientTask, /* Task handle to keep track of created task */
0); /* pin task to core */
@@ -403,14 +416,30 @@ void HTTP_Server::start() {
void HTTP_Server::webClientUpdate(void *pvParameters) {
static unsigned long mDnsTimer = millis(); // NOLINT: There is no overload in String for uint64_t
+ bool recheck = false;
for (;;) {
server.handleClient();
- vTaskDelay(WEBSERVER_DELAY / portTICK_RATE_MS);
+ // vTaskDelay(WEBSERVER_DELAY / portTICK_RATE_MS);
if (WiFi.getMode() != WIFI_MODE_STA) {
+ if (WiFi.softAPgetStationNum()) { // Client Connected to AP
+ httpServer.isServing = true;
+ }
dnsServer.processNextRequest();
+ if (!haveScan) {
+ WiFi_scanNetworks();
+ haveScan = true;
+ }
}
// Keep MDNS alive
if ((millis() - mDnsTimer) > 30000) {
+ if (httpServer.isServing) {
+ if (recheck) {
+ httpServer.isServing = false; // reset BLE communications slowdown.
+ recheck = false;
+ } else {
+ recheck = true; // check again in 30 seconds.
+ }
+ }
MDNS.addServiceTxt("http", "_tcp", "lf", String(mDnsTimer));
mDnsTimer = millis();
#ifdef DEBUG_STACK
@@ -421,29 +450,266 @@ void HTTP_Server::webClientUpdate(void *pvParameters) {
}
void HTTP_Server::handleIndexFile() {
- String filename = "/index.html";
+ httpServer.isServing = true;
+ String filename = "/index.html";
+ server.sendHeader("Connection", "close");
if (LittleFS.exists(filename)) {
- File file = LittleFS.open(filename, FILE_READ);
- server.streamFile(file, "text/html");
+ File file = LittleFS.open(filename, FILE_READ);
+ String page = "";
+ page += FPSTR(HTTP_HEAD_START);
+ page.replace(FPSTR(T_v), DEVICE_NAME);
+ page += FPSTR(HTTP_STYLE);
+ while (file.available()) {
+ page += char(file.read());
+ }
+ server.send(200, "text/html", page);
+ // server.streamFile(file, "text/html");
file.close();
SS2K_LOG(HTTP_SERVER_LOG_TAG, "Served %s", filename.c_str());
} else {
SS2K_LOG(HTTP_SERVER_LOG_TAG, "%s not found. Sending builtin Index.html", filename.c_str());
- server.send(200, "text/html", noIndexHTML);
+ server.send(200, "text/html", httpServer.processWiFiHTML());
+ }
+}
+
+String HTTP_Server::processWiFiHTML() {
+ String page = getHTTPHead(); // @token titlewifi
+ if (!haveScan) {
+ WiFi_scanNetworks(); // wifiscan, force if arg refresh
+ }
+
+ page.replace(FPSTR(T_1), reinterpret_cast(WIFI_PAGE_TITLE));
+ page += getScanItemOut();
+
+ String pitem = "";
+
+ pitem = FPSTR(HTTP_FORM_START);
+ pitem.replace(FPSTR(T_v), F("send_settings")); // set form action
+ page += pitem;
+
+ pitem = FPSTR(HTTP_FORM_WIFI);
+ pitem.replace(FPSTR(T_v), reinterpret_cast(userConfig.getSsid()));
+
+ pitem.replace(FPSTR(T_p), reinterpret_cast(DEFAULT_PASSWORD));
+
+ page += pitem;
+
+ page += FPSTR(HTTP_BR);
+ page += FPSTR(HTTP_FORM_WIFI_END);
+ page += FPSTR(HTTP_FORM_END);
+ page += FPSTR(HTTP_SCAN_LINK);
+ if (!LittleFS.exists("/index.html")) {
+ page += FPSTR(NOINDEXHTML);
}
+ page += FPSTR(HTTP_REBOOT_LINK);
+
+ page += FPSTR(HTTP_END);
+
+ return page;
+}
+
+bool WiFi_scanNetworks() {
+ // if 0 networks, rescan @note this was a kludge, now disabling to test real cause ( maybe wifi not init etc)
+ // enable only if preload failed?
+ if (_numNetworks == 0) {
+ SS2K_LOG(HTTP_SERVER_LOG_TAG, "NO APs found forcing new scan");
+ }
+
+ int8_t res;
+
+ SS2K_LOG(HTTP_SERVER_LOG_TAG, "WiFi Scan SYNC started");
+ res = WiFi.scanNetworks();
+
+ if (res == WIFI_SCAN_FAILED) {
+ SS2K_LOG(HTTP_SERVER_LOG_TAG, "WiFi Scan failed");
+ } else if (res == WIFI_SCAN_RUNNING) {
+ while (WiFi.scanComplete() == WIFI_SCAN_RUNNING) {
+ Serial.print(".");
+ delay(100);
+ }
+ _numNetworks = WiFi.scanComplete();
+ } else if (res >= 0) {
+ _numNetworks = res;
+ haveScan = true;
+ }
+
+ if (res > 0) {
+ // Serial.printf("Networks found: %d", _numNetworks);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+String getHTTPHead() {
+ String page;
+ page += FPSTR(HTTP_HEAD_START);
+ page.replace(FPSTR(T_v), DEVICE_NAME);
+ page += FPSTR(HTTP_SCRIPT);
+ page += FPSTR(HTTP_STYLE);
+ page += FPSTR(HTTP_TITLE);
+ page += FPSTR(HTTP_HEAD_END);
+ return page;
+}
+
+String getScanItemOut() {
+ String page;
+
+ if (!_numNetworks) WiFi_scanNetworks(); // scan in case this gets called before any scans
+
+ int n = _numNetworks;
+ if (n == 0) {
+#ifdef WM_DEBUG_LEVEL
+ DEBUG_WM(F("No networks found"));
+#endif
+ page += FPSTR(S_nonetworks); // @token nonetworks
+ page += F(" ");
+ } else {
+#ifdef WM_DEBUG_LEVEL
+ DEBUG_WM(n, F("networks found"));
+#endif
+ // sort networks
+ int indices[n];
+ for (int i = 0; i < n; i++) {
+ indices[i] = i;
+ }
+
+ // RSSI SORT
+ for (int i = 0; i < n; i++) {
+ for (int j = i + 1; j < n; j++) {
+ if (WiFi.RSSI(indices[j]) > WiFi.RSSI(indices[i])) {
+ std::swap(indices[i], indices[j]);
+ }
+ }
+ }
+
+ /* test std:sort
+ std::sort(indices, indices + n, [](const int & a, const int & b) -> bool
+ {
+ return WiFi.RSSI(a) > WiFi.RSSI(b);
+ });
+ */
+
+ // remove duplicates ( must be RSSI sorted )
+ String cssid;
+ for (int i = 0; i < n; i++) {
+ if (indices[i] == -1) continue;
+ cssid = WiFi.SSID(indices[i]);
+ for (int j = i + 1; j < n; j++) {
+ if (cssid == WiFi.SSID(indices[j])) {
+#ifdef WM_DEBUG_LEVEL
+ DEBUG_WM(WM_DEBUG_VERBOSE, F("DUP AP:"), WiFi.SSID(indices[j]));
+#endif
+ indices[j] = -1; // set dup aps to index -1
+ }
+ }
+ }
+
+
+ // token precheck, to speed up replacements on large ap lists
+ String HTTP_ITEM_STR = FPSTR(HTTP_ITEM);
+
+ // toggle icons with percentage
+ // HTTP_ITEM_STR.replace("{qp}", FPSTR(HTTP_ITEM_QP));
+ HTTP_ITEM_STR.replace("{qi}", FPSTR(HTTP_ITEM_QI));
+
+ // set token precheck flags
+ bool tok_r = HTTP_ITEM_STR.indexOf(FPSTR(T_r)) > 0;
+ bool tok_R = HTTP_ITEM_STR.indexOf(FPSTR(T_R)) > 0;
+ bool tok_e = HTTP_ITEM_STR.indexOf(FPSTR(T_e)) > 0;
+ bool tok_q = HTTP_ITEM_STR.indexOf(FPSTR(T_q)) > 0;
+ bool tok_i = HTTP_ITEM_STR.indexOf(FPSTR(T_i)) > 0;
+
+ // display networks in page
+ for (int i = 0; i < n; i++) {
+ if (indices[i] == -1) continue; // skip dups
+
+#ifdef WM_DEBUG_LEVEL
+ DEBUG_WM(WM_DEBUG_VERBOSE, F("AP: "), (String)WiFi.RSSI(indices[i]) + " " + (String)WiFi.SSID(indices[i]));
+#endif
+
+ int rssiperc = getRSSIasQuality(WiFi.RSSI(indices[i]));
+ uint8_t enc_type = WiFi.encryptionType(indices[i]);
+
+ if (_minimumQuality == -1 || _minimumQuality < rssiperc) {
+ String item = HTTP_ITEM_STR;
+ if (WiFi.SSID(indices[i]) == "") {
+ // Serial.println(WiFi.BSSIDstr(indices[i]));
+ continue; // No idea why I am seeing these, lets just skip them for now
+ }
+ item.replace(FPSTR(T_V), htmlEntities(WiFi.SSID(indices[i]))); // ssid no encoding
+ item.replace(FPSTR(T_v), htmlEntities(WiFi.SSID(indices[i]), true)); // ssid no encoding
+ if (tok_e) item.replace(FPSTR(T_e), AUTH_MODE_NAMES[enc_type]);
+ if (tok_r) item.replace(FPSTR(T_r), (String)rssiperc); // rssi percentage 0-100
+ if (tok_R) item.replace(FPSTR(T_R), (String)WiFi.RSSI(indices[i])); // rssi db
+ if (tok_q) item.replace(FPSTR(T_q), (String) int(round(map(rssiperc, 0, 100, 1, 4)))); // quality icon 1-4
+ if (tok_i) {
+ if (enc_type != WIFI_AUTH_OPEN) {
+ item.replace(FPSTR(T_i), F("l"));
+ } else {
+ item.replace(FPSTR(T_i), "");
+ }
+ }
+ // Serial.println(WiFi.SSID(indices[i]));
+ page += item;
+ delay(0);
+ } else {
+#ifdef WM_DEBUG_LEVEL
+ DEBUG_WM(WM_DEBUG_VERBOSE, F("Skipping , does not meet _minimumQuality"));
+#endif
+ }
+ }
+ page += FPSTR(HTTP_BR);
+ }
+
+ return page;
+}
+
+int getRSSIasQuality(int RSSI) {
+ int quality = 0;
+ if (RSSI <= -100) {
+ quality = 0;
+ } else if (RSSI >= -50) {
+ quality = 100;
+ } else {
+ quality = 2 * (RSSI + 100);
+ }
+ Serial.println(quality);
+ return quality;
+}
+
+String htmlEntities(String str, bool whitespace) {
+ str.replace("&", "&");
+ str.replace("<", "<");
+ str.replace(">", ">");
+ str.replace("'", "'");
+ if (whitespace) str.replace(" ", " ");
+ return str;
}
void HTTP_Server::handleLittleFSFile() {
- String filename = server.uri();
- int dotPosition = filename.lastIndexOf(".");
- String fileType = filename.substring((dotPosition + 1), filename.length());
+ server.sendHeader("Connection", "close");
+ httpServer.isServing = true;
+ String filename = server.uri();
+ int dotPosition = filename.lastIndexOf(".");
+ String fileType = filename.substring((dotPosition + 1), filename.length());
if (LittleFS.exists(filename)) {
File file = LittleFS.open(filename, FILE_READ);
- if (fileType == "gz") {
- fileType = "html"; // no need to change content type as it's done automatically by .streamfile below VV
+
+ if (fileType == "ico") { // send favicon.ico
+ server.streamFile(file, "image/png");
+ } else {
+ String page = "";
+ page += FPSTR(HTTP_HEAD_START);
+ page.replace(FPSTR(T_v), DEVICE_NAME);
+ page += FPSTR(HTTP_STYLE);
+ while (file.available()) {
+ page += char(file.read());
+ }
+ server.send(200, "text/html", page);
}
- server.streamFile(file, "text/" + fileType);
file.close();
+
SS2K_LOG(HTTP_SERVER_LOG_TAG, "Served %s", filename.c_str());
} else if (!LittleFS.exists("/index.html")) {
SS2K_LOG(HTTP_SERVER_LOG_TAG, "%s not found and no filesystem. Sending builtin index.html", filename.c_str());
@@ -463,11 +729,17 @@ void HTTP_Server::settingsProcessor() {
if (!server.arg("ssid").isEmpty()) {
tString = server.arg("ssid");
tString.trim();
+ if (tString != userConfig.getSsid()) {
+ reboot = true;
+ }
userConfig.setSsid(tString);
}
if (!server.arg("password").isEmpty()) {
tString = server.arg("password");
tString.trim();
+ if (tString != userConfig.getPassword()) {
+ reboot = true;
+ }
userConfig.setPassword(tString);
}
if (!server.arg("deviceName").isEmpty()) {
@@ -746,21 +1018,21 @@ void HTTP_Server::FirmwareUpdate() {
//////// Update Firmware /////////
SS2K_LOG(HTTP_SERVER_LOG_TAG, "Updating Firmware...Please Wait");
if (((availableVer > currentVer) || updateAnyway) && (userConfig.getAutoUpdate())) {
- t_httpUpdate_return ret = httpUpdate.update(client, userConfig.getFirmwareUpdateURL() + String(FW_BINFILE));
- switch (ret) {
- case HTTP_UPDATE_FAILED:
- SS2K_LOG(HTTP_SERVER_LOG_TAG, "HTTP_UPDATE_FAILED Error %d : %s", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str());
- break;
-
- case HTTP_UPDATE_NO_UPDATES:
- SS2K_LOG(HTTP_SERVER_LOG_TAG, "HTTP_UPDATE_NO_UPDATES");
- break;
-
- case HTTP_UPDATE_OK:
- SS2K_LOG(HTTP_SERVER_LOG_TAG, "HTTP_UPDATE_OK");
- break;
- }
+ t_httpUpdate_return ret = httpUpdate.update(client, userConfig.getFirmwareUpdateURL() + String(FW_BINFILE));
+ switch (ret) {
+ case HTTP_UPDATE_FAILED:
+ SS2K_LOG(HTTP_SERVER_LOG_TAG, "HTTP_UPDATE_FAILED Error %d : %s", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str());
+ break;
+
+ case HTTP_UPDATE_NO_UPDATES:
+ SS2K_LOG(HTTP_SERVER_LOG_TAG, "HTTP_UPDATE_NO_UPDATES");
+ break;
+
+ case HTTP_UPDATE_OK:
+ SS2K_LOG(HTTP_SERVER_LOG_TAG, "HTTP_UPDATE_OK");
+ break;
}
+ }
} else { // don't update
SS2K_LOG(HTTP_SERVER_LOG_TAG, " - Current Version: %s", FIRMWARE_VERSION);
}
diff --git a/src/Main.cpp b/src/Main.cpp
index 4ba17555..ebc4e66b 100644
--- a/src/Main.cpp
+++ b/src/Main.cpp
@@ -190,7 +190,7 @@ void SS2K::maintenanceLoop(void *pvParameters) {
static int loopCounter = 0;
static unsigned long intervalTimer = millis();
static unsigned long intervalTimer2 = millis();
- static bool isScanning = false;
+ // static bool isScanning = false;
while (true) {
vTaskDelay(73 / portTICK_RATE_MS);
@@ -208,18 +208,18 @@ void SS2K::maintenanceLoop(void *pvParameters) {
intervalTimer = millis();
}
- if ((millis() - intervalTimer2) > 6007) {
- if (NimBLEDevice::getScan()->isScanning()) { // workaround to prevent occasional runaway scans
- if (isScanning == true) {
- SS2K_LOGW(MAIN_LOG_TAG, "Forcing Scan to stop.");
- NimBLEDevice::getScan()->stop();
- isScanning = false;
- } else {
- isScanning = true;
+ /* if ((millis() - intervalTimer2) > 6007) {
+ if (NimBLEDevice::getScan()->isScanning()) { // workaround to prevent occasional runaway scans
+ if (isScanning == true) {
+ SS2K_LOGW(MAIN_LOG_TAG, "Forcing Scan to stop.");
+ NimBLEDevice::getScan()->stop();
+ isScanning = false;
+ } else {
+ isScanning = true;
+ }
}
- }
- intervalTimer2 = millis();
- }
+ intervalTimer2 = millis();
+ }*/
if (loopCounter > 10) {
ss2k.checkDriverTemperature();
// ss2k.checkBLEReconnect();
diff --git a/src/SensorCollector.cpp b/src/SensorCollector.cpp
index 6d13e504..e03c82a8 100644
--- a/src/SensorCollector.cpp
+++ b/src/SensorCollector.cpp
@@ -66,11 +66,8 @@ void collectAndSet(NimBLEUUID charUUID, NimBLEUUID serviceUUID, NimBLEAddress ad
}
}
strncat(logBuf + logBufLength, " ]", kLogBufMaxLength - logBufLength);
- if (userConfig.getLogComm()) {
- SS2K_LOG(BLE_COMMON_LOG_TAG, "%s", logBuf);
- } else {
- SS2K_LOG(BLE_COMMON_LOG_TAG, "rx %s", sensorData->getId().c_str());
- }
+
+ SS2K_LOG(BLE_COMMON_LOG_TAG, "%s", logBuf);
#ifdef USE_TELEGRAM
SEND_TO_TELEGRAM(String(logBuf));
#endif
diff --git a/src/WebsocketAppender.cpp b/src/WebsocketAppender.cpp
index bf715e1d..06c05fee 100644
--- a/src/WebsocketAppender.cpp
+++ b/src/WebsocketAppender.cpp
@@ -31,6 +31,9 @@ void WebSocketAppender::Loop() {
void WebSocketAppender::Log(const char* message) {
// Serial.println("Log websocket.");
// Serial.printf("%d clients connected.\n", GetClientsCount());
+ if(!userConfig.getLogComm()){
+ return;
+ }
for (uint8_t index = 0; index < maxClients; index++) {
WebsocketsClient* client = _clients[index];