Release v1.3.4.2 - fix isEscape bug, power-loss resilience, EEPROM fix, SD mutex, code cleanup

This commit is contained in:
2026-05-10 18:39:11 +02:00
parent 84e2abae14
commit 10d187eb37
29 changed files with 3482 additions and 0 deletions

View File

@@ -0,0 +1,275 @@
#include <Network.h>
#include <SD.h>
static const char *WIFI = "wifi";
extern ConfigManager configManager;
WiFiManager::WiFiManager() {}
void WiFiManager::begin() {
ESP_LOGI(WIFI, "Start network");
isAccessPoint = config.connect;
if (!isAccessPoint) {
setupAccessPoint(ssidAP.c_str(), passwordAP.c_str());
} else {
ESP_LOGI(WIFI, "WiFi client");
ReadConnection();
connectToWiFi();
}
getRSSI();
setupMDNS();
}
// Konwersja char na IPAddress
bool WiFiManager::convertCharToIPAddress(const char *str, IPAddress& ip) {
uint8_t octets[4];
int parsed = sscanf(str, "%hhu.%hhu.%hhu.%hhu", &octets[0], &octets[1], &octets[2], &octets[3]);
if (parsed == 4) {
ip = IPAddress(octets[0], octets[1], octets[2], octets[3]);
return true;
}
return false;
}
void WiFiManager::ReadConnection() {
ESP_LOGE(WIFI, "Network config error");
isAccessPoint = config.connect;
useDHCP = config.dhcp;
convertCharToIPAddress(config.ip, local_IP);
convertCharToIPAddress(config.gateway, gateway);
convertCharToIPAddress(config.subnet, subnet);
convertCharToIPAddress(config.dns, dns);
}
void WiFiManager::connectToWiFi() {
ESP_LOGI(WIFI, "WiFi STA mode");
WiFi.mode(WIFI_STA);
WiFi.begin(config.ssid, config.password);
if (!useDHCP) {
if (!WiFi.config(local_IP, gateway, subnet, dns)) {
ESP_LOGE(WIFI, "Network static IP failed");
}
}
ESP_LOGI(WIFI, "WiFi connecting to last SSID: %s", config.ssid);
int retries = 0;
while (WiFi.status() != WL_CONNECTED && retries < 20) {
delay(500);
retries++;
updateLED();
}
if (WiFi.status() != WL_CONNECTED) {
ESP_LOGI(WIFI, "Failed. Reading wifi.txt from SD card...");
File f = SD.open("/wifi.txt");
if (f) {
while (f.available()) {
String line = f.readStringUntil('\n');
line.trim();
if (line.isEmpty()) continue;
int sep = line.indexOf(';');
if (sep > 0) {
String s = line.substring(0, sep);
String p = line.substring(sep + 1);
s.trim();
p.trim();
ESP_LOGI(WIFI, "Trying SSID from list: '%s'", s.c_str());
WiFi.disconnect();
WiFi.begin(s.c_str(), p.c_str());
int tr = 0;
while (WiFi.status() != WL_CONNECTED && tr < 20) {
delay(500);
tr++;
updateLED();
}
if (WiFi.status() == WL_CONNECTED) {
ESP_LOGI(WIFI, "Connected to %s. Saving to config.", s.c_str());
strncpy(config.ssid, s.c_str(), sizeof(config.ssid)-1);
strncpy(config.password, p.c_str(), sizeof(config.password)-1);
configManager.saveConfig();
break;
}
}
}
f.close();
} else {
ESP_LOGW(WIFI, "wifi.txt not found on SD card.");
}
}
if (WiFi.status() == WL_CONNECTED) {
ESP_LOGI(WIFI, "SSID: %s", config.ssid);
String ipString = "IP: " + WiFi.localIP().toString();
ESP_LOGI(WIFI, "%s", ipString.c_str());
String gatewayInfo = "GATEWAY: " + WiFi.gatewayIP().toString();
ESP_LOGI(WIFI, "%s", gatewayInfo.c_str());
String dnsInfo = "DNS: " + WiFi.dnsIP().toString();
ESP_LOGI(WIFI, "%s", dnsInfo.c_str());
} else {
String infoWiFi = "WIFI CONNECTION ERROR: ALL FAILED";
ESP_LOGI(WIFI, "%s", infoWiFi.c_str());
}
updateLED();
}
void WiFiManager::setupAccessPoint(const char *newSSID, const char *newPassword) {
ESP_LOGI(WIFI, "Start AP mode");
// Wyłączenie zapisywania konfiguracji do flash
//WiFi.persistent(false);
// Usunięcie zapisanej konfiguracji trybu stacji
//WiFi.disconnect(true);
//delay(1000);
//WiFi.eraseAP();
//WiFi.enableAP(false);
//WiFi.enableAP(true);
WiFi.mode(WIFI_AP);
WiFi.softAPsetHostname(config.hostname);
WiFi.softAP(newSSID, newPassword);
delay(1000);
String ssi = "AP SSID: " + String(WiFi.softAPSSID());
ESP_LOGI(WIFI, "%s", ssi.c_str());
String sspass = "AP PASS: " + String(newPassword);
ESP_LOGI(WIFI, "%s", sspass.c_str());
IPAddress IP = WiFi.softAPIP();
String ipString = "AP IP: " + IP.toString();
ESP_LOGI(WIFI, "%s", ipString.c_str());
setupMDNS();
getRSSI();
}
bool WiFiManager::isWiFiOK(){
if (WiFi.status() != WL_CONNECTED)
return false;
else
return true;
}
void WiFiManager::checkWiFiConnection() {
if (!isAccessPoint) {
getRSSI();
if (WiFi.status() != WL_CONNECTED) {
String infoWiFi = "WiFi reconnecting: " + String(config.ssid);
ESP_LOGI(WIFI, "%s", infoWiFi.c_str());
WiFi.reconnect();
int retries = 0;
while (WiFi.status() != WL_CONNECTED && retries < 20) {
delay(500);
retries++;
updateLED();
}
if (WiFi.status() == WL_CONNECTED) {
//String infoWiFi = "WiFi connected: " + String(config.ssid);
//ESP_LOGI(WIFI, "%s", infoWiFi.c_str());
//String ipString = "IP: " + WiFi.localIP().toString();
//ESP_LOGI(WIFI, "%s", ipString.c_str());
getRSSI();
setupMDNS();
} else {
String infoWiFi = "WiFi reconnect error: " + String(config.ssid);
ESP_LOGI(WIFI, "%s", infoWiFi.c_str());
getRSSI();
}
}
updateLED();
}
}
int WiFiManager::rssiToPercent(int rssi) {
if (rssi <= -100) {
return 0;
} else
if (rssi >= -50) {
return 100;
}
// Dla wartości pomiędzy -100 a -50 dBm stosujemy prostą liniową skalę
else {
return 2 * (rssi + 100); // Przykładowa liniowa zależność
}
}
void WiFiManager::updateLED() {
getRSSI();
if (WiFi.status() == WL_CONNECTED) {
int8_t rssi = WiFi.RSSI();
if (rssi > -70) {
;
//digitalWrite(LED_PIN, HIGH); // Silny sygnał
} else {
String signalInfo = "WIFI WEAK SIGNAL: " + String(rssi) + " " + rssiToPercent(rssi) + "%";
ESP_LOGW(WIFI, "%s", signalInfo.c_str());
}
}
}
int8_t WiFiManager::getRSSI() {
if (WiFi.status() == WL_CONNECTED) {
rssi = WiFi.RSSI();
return rssi;
}
return 0;
}
void WiFiManager::setupMDNS() {
ESP_LOGI(WIFI, "mDNS start");
if (!MDNS.begin(config.hostname)) {
ESP_LOGE(WIFI, "mDNS error");
} else {
String mdnsstr = "MDNS: http://" + String(config.hostname) + ".local";
ESP_LOGI(WIFI, "%s", mdnsstr.c_str());
}
}
bool WiFiManager::performOTAUpdate(bool allowInsecureTLS, std::function<void(int,int)> progressCb){
// 1) Pobierz i sprawdź URL
String url = String(config.updateUrl); // z Config.h globalny 'config'
url.trim();
if (url.isEmpty()) {
ESP_LOGE(WIFI, "[OTA] Pusty config.updateUrl przerwano.");
return false;
}
ESP_LOGI(WIFI, "[OTA] URL: %s", url.c_str());
// 2) Wymagamy aktywnego Wi-Fi w trybie klienta
if (WiFi.status() != WL_CONNECTED) {
ESP_LOGE(WIFI, "[OTA] Brak połączenia Wi-Fi przerwano.");
return false;
}
// 3) Callback postępu (opcjonalny)
if (progressCb) {
httpUpdate.onProgress([&](int cur, int total){ progressCb(cur, total); });
}
// 4) Konfiguracja klienta i wywołanie aktualizacji
httpUpdate.rebootOnUpdate(true); // po sukcesie reboot
t_httpUpdate_return ret;
if (url.startsWith("https://")) {
WiFiClientSecure client;
if (allowInsecureTLS) {
client.setInsecure(); // UWAGA: testy/dev; w produkcji lepiej setCACert(...)
}
client.setTimeout(15000);
ret = httpUpdate.update(client, url); // HTTPS
} else {
WiFiClient client;
client.setTimeout(15000);
ret = httpUpdate.update(client, url); // HTTP
}
// 5) Obsługa rezultatów
switch (ret) {
case HTTP_UPDATE_OK:
ESP_LOGI(WIFI, "[OTA] Sukces restart nastąpi za chwilę.");
return true; // reboot i tak zaraz nastąpi
case HTTP_UPDATE_NO_UPDATES:
ESP_LOGW(WIFI, "[OTA] Brak nowej wersji (304/Not Modified).");
return false;
case HTTP_UPDATE_FAILED:
default:
ESP_LOGE(WIFI, "[OTA] Błąd (%d): %s", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str());
return false;
}
}