#include "UploadManager.h" #include "Watchdog.h" static const char* TAG_UPLOAD = "UPLOAD"; static const char* LOG_FILE = "/uploaded.csv"; UploadManager::UploadManager(APIClient& client, RTC_DS3231& rtc, DataCapture& capture) : apiClient(client), rtc_(rtc), capture_(capture) {} String UploadManager::getCurrentTimestamp() { DateTime now = rtc_.now(); char buf[25]; snprintf(buf, sizeof(buf), "%04u-%02u-%02u %02u:%02u:%02u", now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second()); return String(buf); } void UploadManager::appendLog(const String& filePath, const String& status) { File f = SD.open(LOG_FILE, FILE_APPEND); if (f) { f.printf("%s,%s,%s\n", getCurrentTimestamp().c_str(), filePath.c_str(), status.c_str()); f.close(); } } bool UploadManager::isAlreadyUploaded(const String& filePath) { File f = SD.open(LOG_FILE, FILE_READ); if (!f) return false; bool found = false; while (f.available()) { String line = f.readStringUntil('\n'); line.trim(); if (line.length() == 0) continue; int firstComma = line.indexOf(','); if (firstComma < 0) continue; int secondComma = line.indexOf(',', firstComma + 1); if (secondComma < 0) continue; String logPath = line.substring(firstComma + 1, secondComma); String logStatus = line.substring(secondComma + 1); if (logPath == filePath) { if (logStatus == "OK") found = true; else found = false; // A retry might be needed if last status wasn't OK } Watchdog::feed(); } f.close(); return found; } void UploadManager::uploadFile(const String& filePath) { if (isAlreadyUploaded(filePath)) { ESP_LOGI(TAG_UPLOAD, "File %s is already uploaded.", filePath.c_str()); return; } if (WiFi.status() != WL_CONNECTED) { ESP_LOGE(TAG_UPLOAD, "No WiFi. Cannot upload %s", filePath.c_str()); appendLog(filePath, "ERROR: No WiFi"); return; } bool success = apiClient.uploadMeasurement(filePath); if (success) { appendLog(filePath, "OK"); } else { if (WiFi.status() != WL_CONNECTED) { appendLog(filePath, "ERROR: WiFi lost during upload"); } else { appendLog(filePath, "ERROR: Upload Failed"); } } } void UploadManager::processPendingUploads() { if (WiFi.status() != WL_CONNECTED) return; ESP_LOGI(TAG_UPLOAD, "Checking for pending uploads..."); uint32_t highestDir = capture_.findHighestNumericDir(); if (highestDir == 0) return; for (uint32_t d = 1; d <= highestDir; d++) { String path = capture_.dirPath(d); File dir = SD.open(path); if (!dir || !dir.isDirectory()) { if(dir) dir.close(); continue; } for (File f = dir.openNextFile(); f; f = dir.openNextFile()) { if (f.isDirectory()) { f.close(); continue; } String childPath = String(f.name()); if (!childPath.startsWith("/")) { childPath = path + "/" + childPath; } if (childPath.endsWith(".wmt")) { if (!isAlreadyUploaded(childPath)) { ESP_LOGI(TAG_UPLOAD, "Found pending file: %s", childPath.c_str()); uploadFile(childPath); delay(1000); } } f.close(); Watchdog::feed(); if (WiFi.status() != WL_CONNECTED) { dir.close(); return; } } dir.close(); } ESP_LOGI(TAG_UPLOAD, "Pending uploads check complete."); }