11 Commits
main ... WMT_PW

Author SHA1 Message Date
Victus
121c0008f9 Usuniecie logow DEBUG z APIClient, UploadManager i main 2026-05-11 10:55:39 +02:00
Victus
8b0255e403 Wdrozenie 3 etapowego flagowania z wysylaniem ACK do serwera podczas uploadu 2026-05-11 01:40:09 +02:00
Victus
b82f19a27a Wdrozenie pobierania konfiguracji WiFi przez polling zewnetrznego serwera API (GET /config/wifi?sn=...) 2026-05-11 01:23:33 +02:00
Victus
1e2dc7a3aa Revert "Dodanie REST API w tle (endpoint /api/wifi) sluzacego do zdalnego dopisywania nowej sieci WiFi do pliku konfiguracyjnego w czasie normalnej pracy"
This reverts commit 37b9c8160f.
2026-05-11 01:21:38 +02:00
Victus
7699c48fcb Reapply "Zmiana hostnamu mDNS na numer seryjny z restUser"
This reverts commit ec823c7a06.
2026-05-11 01:21:25 +02:00
Victus
ec823c7a06 Revert "Zmiana hostnamu mDNS na numer seryjny z restUser"
This reverts commit 967672bc26.
2026-05-11 01:21:18 +02:00
Victus
967672bc26 Zmiana hostnamu mDNS na numer seryjny z restUser 2026-05-11 01:17:33 +02:00
Victus
37b9c8160f Dodanie REST API w tle (endpoint /api/wifi) sluzacego do zdalnego dopisywania nowej sieci WiFi do pliku konfiguracyjnego w czasie normalnej pracy 2026-05-11 00:55:25 +02:00
Victus
7d997ed543 Naprawa isPressed() - dodanie wykrywania zbocza opadajacego, co rozwiazuje problem wielokrotnego wyzwalania akcji przy przytrzymaniu 2026-05-11 00:39:26 +02:00
Victus
7f44514172 Dodano synchronizacje zegara RTC z uzyciem NTP (eliminuje ostrzezenie o dacie 1970 z API) 2026-05-11 00:12:34 +02:00
Victus
2cc517c98b Naprawiono wyzwalanie akcji pojedynczego przycisku przy wciskaniu kombinacji UP+OK 2026-05-10 23:49:39 +02:00
7 changed files with 214 additions and 35 deletions

View File

@@ -14,6 +14,9 @@ public:
APIClient();
bool uploadMeasurement(const String& filePath);
int checkDeviceFlags();
bool fetchWiFiConfig();
bool sendWiFiAck();
};
#endif

View File

@@ -47,6 +47,10 @@ private:
void constrainValue(int &value, int minVal, int maxVal);
void printField(const char *label, int value);
bool lastState1_ = true;
bool lastState2_ = true;
bool lastState3_ = true;
};
#endif

View File

@@ -71,7 +71,6 @@ bool APIClient::uploadMeasurement(const String &filePath) {
// Multipart body: head + file data + tail
client.print(head);
ESP_LOGI(TAG_API, "DEBUG: Beginning file read loop");
uint8_t buffer[2048];
while (file.available()) {
@@ -80,10 +79,8 @@ bool APIClient::uploadMeasurement(const String &filePath) {
Watchdog::feed();
}
ESP_LOGI(TAG_API, "DEBUG: File read loop finished. Writing tail.");
client.print(tail);
file.close();
ESP_LOGI(TAG_API, "DEBUG: Tail written. Waiting for response...");
// --- Parsowanie odpowiedzi ---
int httpCode = 0;
@@ -101,7 +98,6 @@ bool APIClient::uploadMeasurement(const String &filePath) {
}
Watchdog::feed();
}
ESP_LOGI(TAG_API, "DEBUG: Header parsing loop finished. httpCode: %d", httpCode);
String responseBody = "";
while (client.available()) {
@@ -126,3 +122,145 @@ bool APIClient::uploadMeasurement(const String &filePath) {
return false;
}
bool APIClient::fetchWiFiConfig() {
if (WiFi.status() != WL_CONNECTED) {
return false;
}
HTTPClient http;
String url = String(config.restURL) + ":" + String(config.restPort) + "/config/wifi?sn=" + String(config.restUser);
ESP_LOGI(TAG_API, "Fetching WiFi config from: %s", url.c_str());
http.begin(url);
http.setAuthorization(config.restUser, config.restPass);
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK || httpCode == 200) {
String payload = http.getString();
ESP_LOGI(TAG_API, "Received config payload: %s", payload.c_str());
int ssidStart = payload.indexOf("\"ssid\"");
int passStart = payload.indexOf("\"password\"");
if (ssidStart >= 0 && passStart >= 0) {
int ssidValStart = payload.indexOf("\"", ssidStart + 6);
ssidValStart = payload.indexOf("\"", ssidValStart + 1) + 1;
int ssidValEnd = payload.indexOf("\"", ssidValStart);
String newSSID = payload.substring(ssidValStart, ssidValEnd);
int passValStart = payload.indexOf("\"", passStart + 10);
passValStart = payload.indexOf("\"", passValStart + 1) + 1;
int passValEnd = payload.indexOf("\"", passValStart);
String newPass = payload.substring(passValStart, passValEnd);
if (newSSID.length() > 0) {
bool alreadyExists = false;
File fr = SD.open("/wifi.txt", FILE_READ);
if (fr) {
while(fr.available()) {
String line = fr.readStringUntil('\n');
line.trim();
if (line == (newSSID + ";" + newPass)) {
alreadyExists = true;
break;
}
}
fr.close();
}
if (!alreadyExists) {
File fw = SD.open("/wifi.txt", FILE_APPEND);
if (fw) {
fw.println(newSSID + ";" + newPass);
fw.close();
ESP_LOGI(TAG_API, "Saved new WiFi config to SD: %s", newSSID.c_str());
sendWiFiAck();
http.end();
return true;
}
} else {
ESP_LOGI(TAG_API, "WiFi config already exists, skipping.");
sendWiFiAck();
http.end();
return true;
}
}
} else {
ESP_LOGE(TAG_API, "Invalid JSON format received (missing ssid/password keys)");
}
} else if (httpCode == 404) {
ESP_LOGI(TAG_API, "No new WiFi config available (HTTP 404)");
} else {
ESP_LOGE(TAG_API, "fetchWiFiConfig failed, HTTP code: %d", httpCode);
}
http.end();
return false;
}
int APIClient::checkDeviceFlags() {
if (WiFi.status() != WL_CONNECTED) {
return -1;
}
HTTPClient http;
String url = String(config.restURL) + ":" + String(config.restPort) + "/config/flags?sn=" + String(config.restUser);
ESP_LOGI(TAG_API, "Checking flags from: %s", url.c_str());
http.begin(url);
http.setAuthorization(config.restUser, config.restPass);
int httpCode = http.GET();
int flagValue = -1;
if (httpCode == HTTP_CODE_OK || httpCode == 200) {
String payload = http.getString();
int flagStart = payload.indexOf("\"wifi_update\"");
if (flagStart >= 0) {
int valStart = payload.indexOf(":", flagStart) + 1;
int valEnd = payload.indexOf("}", valStart);
if (valEnd < 0) valEnd = payload.indexOf(",", valStart);
String valStr = payload.substring(valStart, valEnd);
valStr.trim();
flagValue = valStr.toInt();
ESP_LOGI(TAG_API, "Flag wifi_update detected: %d", flagValue);
} else {
ESP_LOGE(TAG_API, "Flag wifi_update not found in JSON");
}
} else {
ESP_LOGE(TAG_API, "Failed to check flags. HTTP code: %d", httpCode);
}
http.end();
return flagValue;
}
bool APIClient::sendWiFiAck() {
if (WiFi.status() != WL_CONNECTED) {
return false;
}
HTTPClient http;
String url = String(config.restURL) + ":" + String(config.restPort) + "/config/wifi/ack?sn=" + String(config.restUser);
ESP_LOGI(TAG_API, "Sending ACK to: %s", url.c_str());
http.begin(url);
http.setAuthorization(config.restUser, config.restPass);
http.addHeader("Content-Type", "application/json");
int httpCode = http.POST("{\"status\":\"ok\"}");
bool success = false;
if (httpCode == HTTP_CODE_OK || httpCode == 200 || httpCode == 201) {
ESP_LOGI(TAG_API, "ACK sent successfully");
success = true;
} else {
ESP_LOGE(TAG_API, "Failed to send ACK. HTTP code: %d", httpCode);
}
http.end();
return success;
}

View File

@@ -213,10 +213,10 @@ int8_t WiFiManager::getRSSI() {
void WiFiManager::setupMDNS() {
ESP_LOGI(WIFI, "mDNS start");
if (!MDNS.begin(config.hostname)) {
if (!MDNS.begin(config.restUser)) {
ESP_LOGE(WIFI, "mDNS error");
} else {
String mdnsstr = "MDNS: http://" + String(config.hostname) + ".local";
String mdnsstr = "MDNS: http://" + String(config.restUser) + ".local";
ESP_LOGI(WIFI, "%s", mdnsstr.c_str());
}
}

View File

@@ -13,15 +13,28 @@ void Settings::begin() {
pinMode(BTN_DOWN, INPUT_PULLUP);
}
// Zwraca true, jeśli przycisk jest wciśnięty
// Zwraca true, jeśli przycisk został WŁAŚNIE wciśnięty (zbocze opadające)
bool Settings::isPressed(uint8_t btnIndex) {
//ESP_LOGI(TAG_SETTINGS, "BTN check");
bool currentState, isNewlyPressed = false;
switch (btnIndex) {
case 1: return digitalRead(BTN_UP) == LOW;
case 2: return digitalRead(BTN_OK) == LOW;
case 3: return digitalRead(BTN_DOWN) == LOW;
case 1:
currentState = digitalRead(BTN_UP);
isNewlyPressed = (currentState == LOW && lastState1_ == HIGH);
lastState1_ = currentState;
break;
case 2:
currentState = digitalRead(BTN_OK);
isNewlyPressed = (currentState == LOW && lastState2_ == HIGH);
lastState2_ = currentState;
break;
case 3:
currentState = digitalRead(BTN_DOWN);
isNewlyPressed = (currentState == LOW && lastState3_ == HIGH);
lastState3_ = currentState;
break;
default: return false;
}
return isNewlyPressed;
}
// Kombinacja 1 i 3 jednocześnie

View File

@@ -63,9 +63,7 @@ void UploadManager::uploadFile(const String& filePath) {
return;
}
ESP_LOGI(TAG_UPLOAD, "DEBUG: Before apiClient.uploadMeasurement");
bool success = apiClient.uploadMeasurement(filePath);
ESP_LOGI(TAG_UPLOAD, "DEBUG: After apiClient.uploadMeasurement. Success: %d", success);
if (success) {
appendLog(filePath, "OK");
} else {
@@ -80,15 +78,19 @@ void UploadManager::uploadFile(const String& filePath) {
void UploadManager::processPendingUploads() {
if (WiFi.status() != WL_CONNECTED) return;
ESP_LOGI(TAG_UPLOAD, "Checking API flags...");
int flags = apiClient.checkDeviceFlags();
if (flags == 1) {
ESP_LOGI(TAG_UPLOAD, "Flag = 1. Fetching new WiFi config...");
apiClient.fetchWiFiConfig();
}
ESP_LOGI(TAG_UPLOAD, "Checking for pending uploads...");
ESP_LOGI(TAG_UPLOAD, "DEBUG: findHighestNumericDir()");
uint32_t highestDir = capture_.findHighestNumericDir();
ESP_LOGI(TAG_UPLOAD, "DEBUG: highestDir: %u", highestDir);
if (highestDir == 0) return;
for (uint32_t d = 1; d <= highestDir; d++) {
String path = capture_.dirPath(d);
ESP_LOGI(TAG_UPLOAD, "DEBUG: Scanning dir: %s", path.c_str());
File dir = SD.open(path);
if (!dir || !dir.isDirectory()) {
if(dir) dir.close();
@@ -105,9 +107,7 @@ void UploadManager::processPendingUploads() {
if (childPath.endsWith(".wmt")) {
if (!isAlreadyUploaded(childPath)) {
ESP_LOGI(TAG_UPLOAD, "Found pending file: %s", childPath.c_str());
ESP_LOGI(TAG_UPLOAD, "DEBUG: Calling uploadFile()");
uploadFile(childPath);
ESP_LOGI(TAG_UPLOAD, "DEBUG: Finished uploadFile(), delaying 1000ms");
delay(1000);
}
}

View File

@@ -17,6 +17,7 @@
#include <Settings.h>
#include "APIClient.h"
#include "UploadManager.h"
#include <time.h>
#define WDT_TIMEOUT 60 // Czas watchdoga do restartu
#define MAX_ADXL345_SENSORS 4 // Maksymalna ilość podłączanych sensorów
@@ -64,6 +65,7 @@ void checkWiFi();
void showOfflineScreen();
void measure();
void setClockRTCBtn();
void syncNTP();
/* ******************* SETUP() ************************* */
void setup() {
@@ -213,6 +215,7 @@ void setup() {
if(config.connect){
wifi.begin();
syncNTP(); // Zaktualizuj RTC z internetu od razu po połączniu z WiFi
wifiTestThread.onRun(checkWiFi);
wifiTestThread.setInterval(5000); // Test WiFi co 3 sekundy
} else {
@@ -347,7 +350,6 @@ void measure(){
Watchdog::feed();
if(!capture.isExit){
capture.printLastFileInfoSerial();
ESP_LOGI(TAG_MAIN, "DEBUG: before readHeaderAndPrint");
capture.readHeaderAndPrint(capture.generateNextFilename().c_str());
ESP_LOGI(TAG_MAIN, "MEASURE FINISH");
} else {
@@ -355,12 +357,9 @@ void measure(){
//runMeasure = false;
}
ESP_LOGI(TAG_MAIN, "DEBUG: Checking WiFi status for upload");
if (config.connect && WiFi.status() == WL_CONNECTED) {
ESP_LOGI(TAG_MAIN, "TRIGGER UPLOAD PENDING...");
ESP_LOGI(TAG_MAIN, "DEBUG: Before uploadManager.processPendingUploads()");
uploadManager.processPendingUploads();
ESP_LOGI(TAG_MAIN, "DEBUG: After uploadManager.processPendingUploads()");
}
runMeasure = false;
@@ -383,8 +382,39 @@ void settingsDevice(){
settings.finishConfigDevice();
}
void syncNTP() {
if (WiFi.status() == WL_CONNECTED) {
ESP_LOGI(TAG_MAIN, "Syncing RTC with NTP server...");
configTime(3600, 3600, "pool.ntp.org", "time.nist.gov"); // Strefa czasowa CET (+1h, +1h DST)
struct tm timeinfo;
if (getLocalTime(&timeinfo, 10000)) { // Czekaj max 10 sekund na czas z neta
rtc.adjust(DateTime(timeinfo.tm_year + 1900, timeinfo.tm_mon + 1, timeinfo.tm_mday, timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec));
ESP_LOGI(TAG_MAIN, "NTP Time synced! New RTC date: %d-%d-%d", timeinfo.tm_year + 1900, timeinfo.tm_mon + 1, timeinfo.tm_mday);
} else {
ESP_LOGE(TAG_MAIN, "NTP Sync failed. Using old RTC date.");
}
}
}
///////////// LOOP ////////////////////////////////////////////
void loop() {
if (settings.readBtnUp() || settings.readBtnDown() || settings.readBtnOk()) {
delay(50); // Krótkie opóźnienie na "wciśnięcie drugiego przycisku"
if (settings.readBtnUp() && settings.readBtnOk()) {
ESP_LOGI(TAG_MAIN, "Manual AP Mode trigger");
wifi.startCaptivePortal();
display.clear();
display.textCenter(1, "AP MODE");
display.textCenter(2, "192.168.4.1");
while(settings.readBtnUp() || settings.readBtnOk() || settings.readBtnDown()) {
Watchdog::feed();
delay(50);
}
delay(200); // Odczekanie po puszczeniu przycisków, żeby nie wywołać innych akcji
return;
}
}
if (settings.isPressed(2)){
Watchdog::feed();
if(runMeasure) {
@@ -403,17 +433,7 @@ void loop() {
if(settings.isPressed(3)) settingsDevice(); // DOWN
if(settings.isPressed(1)) toogleMode(); // UP
if (settings.readBtnUp() && settings.readBtnOk()) {
ESP_LOGI(TAG_MAIN, "Manual AP Mode trigger");
wifi.startCaptivePortal();
display.clear();
display.textCenter(1, "AP MODE");
display.textCenter(2, "192.168.4.1");
while(settings.readBtnUp() && settings.readBtnOk()) {
Watchdog::feed();
delay(50);
}
}
if(testingNow) {
if((runMeasure) && (settings.isPressed(2))){
@@ -426,9 +446,10 @@ void loop() {
if(wifiTestThread.shouldRun() && (config.connect))
wifiTestThread.run();
if(uploadThread.shouldRun() && config.connect)
if(config.connect){
uploadThread.run();
}
if(offlineThread.shouldRun() && (!config.connect)){
offlineThread.run();
}