From bf261b96caa5098b418db72515d450af93793a1b Mon Sep 17 00:00:00 2001 From: Sjef Verhoeven PE5PVB Date: Mon, 13 Jan 2025 23:19:05 +0100 Subject: [PATCH] Add message when logbook is full --- TEF6686_ESP32.ino | 191 ++++++++++++++++++++++++++++------------------ src/language.h | 58 +++++++++----- 2 files changed, 154 insertions(+), 95 deletions(-) diff --git a/TEF6686_ESP32.ino b/TEF6686_ESP32.ino index 59dc457..6c99133 100644 --- a/TEF6686_ESP32.ino +++ b/TEF6686_ESP32.ino @@ -1004,7 +1004,12 @@ void loop() { ShowMemoryPos(); } else { if (!autologged && autolog && RDSstatus && radio.rds.correctPI != 0) { - if (addRowToCSV()) ShowFreq(2); else ShowFreq(3); + switch (addRowToCSV()) { + case 0: ShowFreq(2); break; + case 1: ShowFreq(3); break; + case 2: ShowFreq(4); break; + } + delay(200); while (digitalRead(ROTARY_BUTTON) == LOW) delay(50); ShowFreq(0); @@ -2751,7 +2756,11 @@ void ButtonPress() { } } else { if (band < BAND_GAP) { - if (addRowToCSV()) ShowFreq(2); else ShowFreq(3); + switch (addRowToCSV()) { + case 0: ShowFreq(2); break; + case 1: ShowFreq(3); break; + case 2: ShowFreq(4); break; + } delay(200); while (digitalRead(ROTARY_BUTTON) == LOW) delay(50); ShowFreq(0); @@ -3199,6 +3208,13 @@ void ShowFreq(int mode) { FrequencySprite.pushSprite(46, 46); tftPrint(0, myLanguage[language][291], 146, 58, ActiveColor, ActiveColorSmooth, 28); break; + + case 4: + FrequencySprite.fillSprite(BackgroundColor); + FrequencySprite.pushSprite(46, 46); + tftPrint(0, myLanguage[language][297], 146, 58, ActiveColor, ActiveColorSmooth, 28); + break; + } FrequencySprite.unloadFont(); } @@ -5355,128 +5371,155 @@ void toggleiMSEQ() { } void handleRoot() { - // Open the logbook file fs::File file = SPIFFS.open("/logbook.csv", "r"); if (!file) { webserver.send(500, "text/plain", "Failed to open logbook"); return; } - // Build HTML response String html = ""; html += ""; html += ""; + + // Add CSS styling html += ""; + html += ""; + html += ""; + + // Add logo as a clickable link html += ""; html += "\"FMDX"; html += ""; + html += "

" + String(myLanguage[language][286]) + "

"; html += ""; - html += ""; + html += ""; + + // Sorting function with icons html += ""; - // Generate table header and body - html += ""; - String header = file.available() ? file.readStringUntil('\n') : ""; - if (header.length() > 0) { + html += "
"; + + String header = ""; + if (file.available()) { + header = file.readStringUntil('\n'); + html += ""; int startIndex = 0; int columnIndex = 0; + + // Generate table headers with sorting functionality while (startIndex < header.length()) { int endIndex = header.indexOf(',', startIndex); if (endIndex == -1) endIndex = header.length(); String column = header.substring(startIndex, endIndex); + + // Add clickable headers for sorting html += ""; + html += ""; // Sorting icon placeholder + startIndex = endIndex + 1; columnIndex++; } - html += ""; + html += ""; } - // Generate table rows bool hasData = false; - int piCodeIndex = -1; - int frequencyIndex = -1; - int startIndex = 0; - int columnIndex = 0; + int piCodeIndex = -1, frequencyIndex = -1; + + // Identify column indices for PI code and Frequency + int startIndex = 0, columnIndex = 0; while (startIndex < header.length()) { int endIndex = header.indexOf(',', startIndex); if (endIndex == -1) endIndex = header.length(); String column = header.substring(startIndex, endIndex); + if (column.equalsIgnoreCase("PI code")) piCodeIndex = columnIndex; if (column.equalsIgnoreCase("Frequency")) frequencyIndex = columnIndex; + startIndex = endIndex + 1; columnIndex++; } + // Generate rows while (file.available()) { String line = file.readStringUntil('\n'); if (line.length() > 0) { hasData = true; html += ""; - String piCode = ""; - String frequency = ""; - startIndex = 0; - columnIndex = 0; + + String piCode = "", frequency = ""; + startIndex = 0, columnIndex = 0; + while (startIndex < line.length()) { int endIndex = line.indexOf(',', startIndex); if (endIndex == -1) endIndex = line.length(); String cell = line.substring(startIndex, endIndex); + + // Extract PI code and Frequency if (columnIndex == piCodeIndex) piCode = cell; if (columnIndex == frequencyIndex) frequency = cell; + html += ""; startIndex = endIndex + 1; columnIndex++; } + + // Remove " MHz" from Frequency frequency.replace(" MHz", ""); - html += ""; + + // Make row clickable + html += ""; html += ""; } } - // Handle empty table case file.close(); + if (!hasData) { html += ""; } - html += "
" + column; - html += "
" + cell + "🌐🌐
" + String(myLanguage[language][288]) + "
"; + html += ""; html += ""; + webserver.send(200, "text/html", html); } @@ -5533,76 +5576,74 @@ bool handleCreateNewLogbook() { return true; } -bool addRowToCSV() { - // Check if there is enough free space in SPIFFS (150 bytes or more) +byte addRowToCSV() { + // Ensure there is at least 150 bytes of free space in SPIFFS before proceeding if (SPIFFS.totalBytes() - SPIFFS.usedBytes() < 150) { - return false; // Return false if there is less than 150 bytes free + return 2; // Return 2 if insufficient free space is available } - // Open the logbook.csv file in append mode + // Open the "logbook.csv" file in append mode fs::File file = SPIFFS.open("/logbook.csv", "a"); // Check if the file could not be opened if (!file) { - return false; // Return false if the file can't be opened + return 1; // Return 1 if the file cannot be opened } - // Get the current date and time from ESP32 (using the built-in time functions) - String currentDateTime = getCurrentDateTime(); // Get the current date and time + // Fetch the current date and time as a string + String currentDateTime = getCurrentDateTime(); - // If time is not available, replace with "-" + // Use a placeholder ("-,-") if the date and time could not be retrieved if (currentDateTime == "") { - currentDateTime = "-,-"; // Set both date and time to "-" + currentDateTime = "-,-"; } - // Convert frequency to a string format (XX.XX MHz) - int freqInt = (int)frequency; // Assuming frequency is already a float or double, cast it to int + // Prepare the frequency in a formatted string (e.g., "XX.XX MHz") + int freqInt = (int)frequency; // Cast the frequency value to an integer + int convertedFreq = (freqInt + ConverterSet * 100) / 100; // Apply necessary conversion + String frequencyFormatted = String(convertedFreq) + "." + + ((freqInt + ConverterSet * 100) % 100 < 10 ? "0" : "") + + String((freqInt + ConverterSet * 100) % 100) + " MHz"; - // Apply the necessary conversion (if any) for frequency - int convertedFreq = (freqInt + ConverterSet * 100) / 100; - String frequencyFormatted = String(convertedFreq) + "." + ((freqInt + ConverterSet * 100) % 100 < 10 ? "0" : "") + String((freqInt + ConverterSet * 100) % 100) + " MHz"; // Add " MHz" - - // Format the signal strength (xx.x with the correct unit) + // Calculate signal strength based on the selected unit int SStatusprint = 0; - if (unit == 0) SStatusprint = SStatus; - if (unit == 1) SStatusprint = ((SStatus * 100) + 10875) / 100; - if (unit == 2) SStatusprint = round((float(SStatus) / 10.0 - 10.0 * log10(75) - 90.0) * 10.0); + if (unit == 0) SStatusprint = SStatus; // dBμV + if (unit == 1) SStatusprint = ((SStatus * 100) + 10875) / 100; // dBf + if (unit == 2) SStatusprint = round((float(SStatus) / 10.0 - 10.0 * log10(75) - 90.0) * 10.0); // dBm - // Choose the correct unit suffix for signal based on the `unit` value + // Format the signal strength with appropriate decimal places and unit String signal = String(SStatusprint / 10) + "." + String(abs(SStatusprint % 10)); - if (unit == 0) { - signal += " dBμV"; // Unit for unit == 0 - } else if (unit == 1) { - signal += " dBf"; // Unit for unit == 1 - } else if (unit == 2) { - signal += " dBm"; // Unit for unit == 2 - } + if (unit == 0) signal += " dBμV"; + else if (unit == 1) signal += " dBf"; + else if (unit == 2) signal += " dBm"; - // Format the RadioText with enhanced option if available + // Prepare the radio text with station information, including enhanced options if available String radioText = String(radio.rds.stationText + " " + radio.rds.stationText32); if (radio.rds.hasEnhancedRT) { radioText += " eRT: " + String(radio.rds.enhancedRTtext); } - // Replace commas in the station name and radioText just when adding to the row + // Replace commas in the station name and radio text to avoid CSV conflicts String stationName = radio.rds.stationName; String radioTextModified = radioText; + stationName.replace(",", " "); // Replace commas in station name + radioTextModified.replace(",", " "); // Replace commas in radio text - stationName.replace(",", " "); // Temporarily replace commas in stationName - radioTextModified.replace(",", " "); // Temporarily replace commas in radioText + // Construct the CSV row data + String row = currentDateTime + "," + + frequencyFormatted + "," + + radio.rds.picode + "," + + signal + "," + + stationName + "," + + radioTextModified + "\n"; - // Create the row data, replacing stationIDtext with picode - String row = currentDateTime + "," + frequencyFormatted + "," + radio.rds.picode + "," + signal + "," + stationName + "," + radioTextModified + "\n"; - - // Write the row to the CSV file + // Write the row to the file and close it if (file.print(row)) { - // Successfully wrote to the file - file.close(); - return true; // Return true when the row is successfully added + file.close(); // Successfully wrote to the file + return 0; // Return 0 to indicate success } else { - // Failed to write to the file - file.close(); - return false; // Return false if there was an issue writing + file.close(); // Close the file if writing fails + return 1; // Return 1 to indicate failure } } diff --git a/src/language.h b/src/language.h index f937fdf..801ad48 100644 --- a/src/language.h +++ b/src/language.h @@ -5,7 +5,7 @@ // [number of languages][number of texts] -static const char* const myLanguage[18][297] PROGMEM = { +static const char* const myLanguage[18][298] PROGMEM = { { "English", // English "Rotary direction changed", // 1 "Please release button", // 2 @@ -302,7 +302,8 @@ static const char* const myLanguage[18][297] PROGMEM = { "Logbook cleared", // 293 "Clear failed", // 294 "Set NTP time offset", // 295 - "Autologger" // 296 + "Autologger", // 296 + "Logbook full!" // 297 }, { "Nederlands", // Dutch @@ -601,7 +602,8 @@ static const char* const myLanguage[18][297] PROGMEM = { "Logboek geleegd", // 293 "Legen mislukt", // 294 "NTP tijdverschil instellen", // 295 - "Automatisch loggen" // 296 + "Automatisch loggen", // 296 + "Logboek vol!" // 297 }, { "Polski", // Polish @@ -900,7 +902,8 @@ static const char* const myLanguage[18][297] PROGMEM = { "Logbook cleared", // 293 "Clear failed", // 294 "Set NTP time offset", // 295 - "Autologger" // 296 + "Autologger", // 296 + "Logbook full!" // 297 }, { "Hrvatski", // Croatian @@ -1199,7 +1202,8 @@ static const char* const myLanguage[18][297] PROGMEM = { "Logbook cleared", // 293 "Clear failed", // 294 "Set NTP time offset", // 295 - "Autologger" // 296 + "Autologger", // 296 + "Logbook full!" // 297 }, { "Ελληνικά", // Greek @@ -1498,7 +1502,8 @@ static const char* const myLanguage[18][297] PROGMEM = { "Έγινε εκκαθάριση\nτου βιβλίου", // 293 "Η εκκαθάριση απέτυχε", // 294 "Ολίσθηση ώρας NTP", // 295 - "Αυτόματη καταγραφή" // 296 + "Αυτόματη καταγραφή", // 296 + "Logbook full!" // 297 }, { "Română", // Romanian @@ -1797,7 +1802,8 @@ static const char* const myLanguage[18][297] PROGMEM = { "Logbook cleared", // 293 "Clear failed", // 294 "Set NTP time offset", // 295 - "Autologger" // 296 + "Autologger", // 296 + "Logbook full!" // 297 }, { "Deutsch", // German @@ -2096,7 +2102,8 @@ static const char* const myLanguage[18][297] PROGMEM = { "Logbuch gelöscht", // 293 "Löschen fehlgeschlagen", // 294 "NTP-Zeitversatz einstellen", // 295 - "Autologger" // 296 + "Autologger", // 296 + "Logbook full!" // 297 }, { "Český", // Czech @@ -2395,7 +2402,8 @@ static const char* const myLanguage[18][297] PROGMEM = { "Logbook cleared", // 293 "Clear failed", // 294 "Set NTP time offset", // 295 - "Autologger" // 296 + "Autologger", // 296 + "Logbook full!" // 297 }, { "Magyar", // Hungarian @@ -2694,7 +2702,8 @@ static const char* const myLanguage[18][297] PROGMEM = { "Logbook cleared", // 293 "Clear failed", // 294 "Set NTP time offset", // 295 - "Autologger" // 296 + "Autologger", // 296 + "Logbook full!" // 297 }, { "Français", // French @@ -2993,7 +3002,8 @@ static const char* const myLanguage[18][297] PROGMEM = { "Journal de bord\neffacé", // 293 "Échec de l'effacement", // 294 "Décalage horaire NTP", // 295 - "Journal automatique" // 296 + "Journal automatique", // 296 + "Logbook full!" // 297 }, { "Български", // Bulgarian @@ -3292,7 +3302,8 @@ static const char* const myLanguage[18][297] PROGMEM = { "Logbook cleared", // 293 "Clear failed", // 294 "Set NTP time offset", // 295 - "Autologger" // 296 + "Autologger", // 296 + "Logbook full!" // 297 }, { "Русский", // Russian @@ -3591,7 +3602,8 @@ static const char* const myLanguage[18][297] PROGMEM = { "Logbook cleared", // 293 "Clear failed", // 294 "Set NTP time offset", // 295 - "Autologger" // 296 + "Autologger", // 296 + "Logbook full!" // 297 }, { "Українська", // Ukranian @@ -3890,7 +3902,8 @@ static const char* const myLanguage[18][297] PROGMEM = { "Logbook cleared", // 293 "Clear failed", // 294 "Set NTP time offset", // 295 - "Autologger" // 296 + "Autologger", // 296 + "Logbook full!" // 297 }, { "Italiano", // Italian @@ -4189,7 +4202,8 @@ static const char* const myLanguage[18][297] PROGMEM = { "Logbook cancellato", // 293 "Cancellazione non riuscita", // 294 "Imposta offset orario NTP", // 295 - "Autologger" // 296 + "Autologger", // 296 + "Logbook full!" // 297 }, { "Simplified Chinese", // Simplified Chinese @@ -4488,7 +4502,8 @@ static const char* const myLanguage[18][297] PROGMEM = { "Logbook cleared", // 293 "Clear failed", // 294 "Set NTP time offset", // 295 - "Autologger" // 296 + "Autologger", // 296 + "Logbook full!" // 297 }, { "Norsk", // Norwegian @@ -4787,7 +4802,8 @@ static const char* const myLanguage[18][297] PROGMEM = { "Logbook cleared", // 293 "Clear failed", // 294 "Set NTP time offset", // 295 - "Autologger" // 296 + "Autologger", // 296 + "Logbook full!" // 297 }, { "Español", // Spanish @@ -5086,7 +5102,8 @@ static const char* const myLanguage[18][297] PROGMEM = { "Libro de registro\nborrado", // 293 "Error al borrar", // 294 "Desfase de tiempo NTP", // 295 - "Registrador automático" // 296 + "Registrador automático", // 296 + "Logbook full!" // 297 }, { "Português", // Portuguese @@ -5385,7 +5402,8 @@ static const char* const myLanguage[18][297] PROGMEM = { "Livro de registro\nlimpo", // 293 "Falha ao limpar", // 294 "Deslocamento de\ntempo NTP", // 295 - "Registrador automático" // 296 + "Registrador automático", // 296 + "Logbook full!" // 297 } }; -#endif +#endif \ No newline at end of file