diff --git a/TEF6686_ESP32.ino b/TEF6686_ESP32.ino index 99022f7..80c48d7 100644 --- a/TEF6686_ESP32.ino +++ b/TEF6686_ESP32.ino @@ -27,6 +27,7 @@ #include "src/comms.h" #include "src/rds.h" #include "src/touch.h" +#include "src/logbook.h" #define ROTARY_PIN_A 34 #define ROTARY_PIN_B 36 @@ -5393,430 +5394,3 @@ void toggleiMSEQ() { } } } - -void handleRoot() { - fs::File file = SPIFFS.open("/logbook.csv", "r"); - if (!file) { - webserver.send(500, "text/plain", "Failed to open logbook"); - return; - } - - String html = ""; - html += ""; - html += ""; - - // Add CSS styling - html += ""; - html += ""; - - // Add logo as a clickable link - html += ""; - html += "\"FMDX"; - html += ""; - - html += "

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

"; - html += ""; - html += ""; - - // Sorting function with icons - html += ""; - - 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 += ""; // Sorting icon placeholder - - startIndex = endIndex + 1; - columnIndex++; - } - html += ""; - } - - bool hasData = false; - 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++; - } - - if (file.available()) hasData = true; - - if (logcounter < 130) { - // Generate rows - while (file.available()) { - String line = file.readStringUntil('\n'); - if (line.length() > 0) { - html += ""; - - 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", ""); - - // Make row clickable - html += ""; - html += ""; - } - } - - file.close(); - } else { - html += ""; - } - - if (!hasData) { - html += ""; - } - - html += "
" + column; - html += "
" + cell + "🌐
" + String(myLanguage[language][300]) + "
" + String(myLanguage[language][288]) + "
"; - html += ""; - - webserver.send(200, "text/html", html); -} - -void handleDownloadCSV() { - // Attempt to open the CSV file from SPIFFS in read mode - fs::File file = SPIFFS.open("/logbook.csv", "r"); - - // Check if the file was successfully opened - if (!file) { - // If the file could not be opened, send an error response - webserver.send(500, "text/plain", "Failed to open logbook for download"); - return; // Exit the function if the file cannot be opened - } - - // Set the headers to specify that the response will be a CSV file for download - webserver.sendHeader("Content-Type", "text/csv"); // Set MIME type for CSV files - webserver.sendHeader("Content-Disposition", "attachment; filename=logbook.csv"); // Suggests the file name for download - - // Stream the CSV file content directly to the browser - webserver.streamFile(file, "text/csv"); - - // Close the file after streaming the content to release resources - file.close(); -} - -bool handleCreateNewLogbook() { - // Check if the file "logbook.csv" already exists - if (SPIFFS.exists("/logbook.csv")) { - // If it exists, delete the file - if (!SPIFFS.remove("/logbook.csv")) { - // Return false if the file could not be deleted - return false; - } - } - - // Create a new "logbook.csv" file in write mode - fs::File file = SPIFFS.open("/logbook.csv", "w"); - - // Check if the file was successfully created - if (!file) { - // Return false if file creation fails - return false; - } - - // Write the header to the new CSV file - String header = "Date,Time,Frequency,PI code,Signal,Stereo,TA,TP,PTY,PS,RadioText\n"; - file.print(header); // Ensure that the header is written properly - - // Make sure the data is written before closing the file - file.flush(); // Ensure that everything is written to the file - file.close(); // Close the file after writing - - - logcounter = 0; // Reset logcounter - EEPROM.writeUInt(EE_UINT16_LOGCOUNTER, logcounter); - EEPROM.commit(); - // Return true if the function runs without problems - return true; -} - -byte addRowToCSV() { - // Ensure there is at least 150 bytes of free space in SPIFFS before proceeding - if (SPIFFS.totalBytes() - SPIFFS.usedBytes() < 150 || logcounter > 1000) { - return 2; // Return 2 if insufficient free space is available - } - - // 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 1; // Return 1 if the file cannot be opened - } - - // Fetch the current date and time as a string - String currentDateTime = getCurrentDateTime(); - - // Use a placeholder ("-,-") if the date and time could not be retrieved - if (currentDateTime == "") { - currentDateTime = "-,-"; - } - - // 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"; - - // Calculate signal strength based on the selected unit - int SStatusprint = 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 - - // 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"; - else if (unit == 1) signal += " dBf"; - else if (unit == 2) signal += " dBm"; - - // 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 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 - - // Handle PTY, TA, TP and Stereo flag - String TA; - String TP; - String Stereo; - String pty; - if (radio.rds.hasTA) TA = "•"; else TA = ""; - if (radio.rds.hasTP) TP = "•"; else TP = ""; - if (radio.getStereoStatus()) Stereo = "•"; else Stereo = ""; - pty = String(radio.rds.stationTypeCode); - - // Construct the CSV row data - String row = currentDateTime + "," + - frequencyFormatted + "," + - radio.rds.picode + "," + - signal + "," + - Stereo + "," + - TA + "," + - TP + "," + - pty + "," + - stationName + "," + - radioTextModified + "\n"; - - // Write the row to the file and close it - if (file.print(row)) { - file.close(); // Successfully wrote to the file - logcounter++; - EEPROM.writeUInt(EE_UINT16_LOGCOUNTER, logcounter); - EEPROM.commit(); - return 0; // Return 0 to indicate success - } else { - file.close(); // Close the file if writing fails - return 1; // Return 1 to indicate failure - } -} - -String getCurrentDateTime() { - // Check if the RTC has been set - if (!rtcset) { - return "-,-"; // Return placeholder when the RTC is not set - } - - // Use the ESP32's time functions to retrieve the current time - struct tm timeInfo; - if (!getLocalTime(&timeInfo)) { - return "-,-"; // Return placeholder if local time is unavailable - } - - // Adjust timeInfo using the GMT offset - time_t currentEpoch = mktime(&timeInfo); // Convert struct tm to time_t format - - // Calculate GMT offset - currentEpoch += (NTPupdated ? NTPoffset * 3600 : radio.rds.offset); // Apply GMT offset if NTPupdated, else RDS offset - - // Apply DST adjustment if NTPupdated and autoDST are true - if (NTPupdated && autoDST) { - struct tm tempTimeInfo; - localtime_r(¤tEpoch, &tempTimeInfo); // Convert to struct tm for DST calculation - if (isDST(mktime(&tempTimeInfo))) { // Check if DST is in effect - currentEpoch += 3600; // Add 1-hour DST offset - } - } - - // Convert adjusted time back to struct tm format - localtime_r(¤tEpoch, &timeInfo); - - // Buffer for formatted date-time string - char buf[20]; - - if (clockampm) { - // USA format: MM/DD/YYYY, HH:MM:SS AM/PM - strftime(buf, sizeof(buf), "%m/%d/%Y", &timeInfo); // Format as MM/DD/YYYY - - // Format time in 12-hour format with AM/PM - int hour = timeInfo.tm_hour; - String ampm = (hour >= 12) ? "PM" : "AM"; // Determine AM or PM - if (hour == 0) hour = 12; // Convert 0 hour to 12 AM - else if (hour > 12) hour -= 12; // Convert to 12-hour format for PM - - String timeWithAMPM = String(hour) + ":" + (timeInfo.tm_min < 10 ? "0" : "") + String(timeInfo.tm_min) + ":" + (timeInfo.tm_sec < 10 ? "0" : "") + String(timeInfo.tm_sec) + " " + ampm; - - // Return the final formatted date and time for the USA region - return String(buf) + "," + timeWithAMPM; - } else { - // European format: DD-MM-YYYY, HH:MM:SS - strftime(buf, sizeof(buf), "%d-%m-%Y", &timeInfo); // Format as DD-MM-YYYY - String timeEuropean = String(timeInfo.tm_hour) + ":" + (timeInfo.tm_min < 10 ? "0" : "") + String(timeInfo.tm_min) + ":" + (timeInfo.tm_sec < 10 ? "0" : "") + String(timeInfo.tm_sec); // Format time with leading zero if needed - return String(buf) + "," + timeEuropean; - } -} - -bool isDST(time_t t) { - struct tm timeInfo; - localtime_r(&t, &timeInfo); // Convert time_t to struct tm - - int month = timeInfo.tm_mon + 1; // tm_mon is 0-based, so add 1 - int day = timeInfo.tm_mday; // tm_mday is the day of the month - int hour = timeInfo.tm_hour; // tm_hour is the hour of the day - int weekday = timeInfo.tm_wday; // tm_wday is the day of the week (0 = Sunday) - - // DST starts last Sunday in March at 2:00 AM - if (month == 3) { - int lastSunday = 31 - ((weekday + 31 - day) % 7); - if (day > lastSunday || (day == lastSunday && hour >= 2)) { - return true; - } - } - - // DST ends last Sunday in October at 3:00 AM - if (month == 10) { - int lastSunday = 31 - ((weekday + 31 - day) % 7); - if (day < lastSunday || (day == lastSunday && hour < 3)) { - return false; - } - } - - // DST is active from April to September - if (month > 3 && month < 10) { - return true; - } - - return false; -} - -void handleLogo() { - fs::File file = SPIFFS.open("/logo.png", "r"); - if (!file) { - webserver.send(404, "text/plain", "Logo not found"); - return; - } - webserver.streamFile(file, "image/png"); - file.close(); -} - -void printLogbookCSV() { - // Attempt to open the CSV file stored in SPIFFS - fs::File file = SPIFFS.open("/logbook.csv", "r"); - - // Check if the file was successfully opened - if (!file) { - Serial.println("Failed to open logbook!"); - return; - } - - // Print a message indicating the start of the file content - Serial.println("===== Start of logbook.csv ====="); - - // Read and print the contents of the file line by line - while (file.available()) { - String line = file.readStringUntil('\n'); // Read one line at a time - Serial.println(line); // Print the line to the Serial Monitor - } - - // Close the file after reading - file.close(); - - // Print a message indicating the end of the file content - Serial.println("===== End of logbook.csv ====="); -} diff --git a/src/logbook.cpp b/src/logbook.cpp new file mode 100644 index 0000000..7af0175 --- /dev/null +++ b/src/logbook.cpp @@ -0,0 +1,432 @@ +#include "logbook.h" +#include "language.h" +#include "constants.h" +#include +#include "language.h" + +void handleRoot() { + fs::File file = SPIFFS.open("/logbook.csv", "r"); + if (!file) { + webserver.send(500, "text/plain", "Failed to open logbook"); + return; + } + + String html = ""; + html += ""; + html += ""; + + // Add CSS styling + html += ""; + html += ""; + + // Add logo as a clickable link + html += ""; + html += "\"FMDX"; + html += ""; + + html += "

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

"; + html += ""; + html += ""; + + // Sorting function with icons + html += ""; + + 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 += ""; // Sorting icon placeholder + + startIndex = endIndex + 1; + columnIndex++; + } + html += ""; + } + + bool hasData = false; + 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++; + } + + if (file.available()) hasData = true; + + if (logcounter < 130) { + // Generate rows + while (file.available()) { + String line = file.readStringUntil('\n'); + if (line.length() > 0) { + html += ""; + + 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", ""); + + // Make row clickable + html += ""; + html += ""; + } + } + + file.close(); + } else { + html += ""; + } + + if (!hasData) { + html += ""; + } + + html += "
" + column; + html += "
" + cell + "🌐
" + String(myLanguage[language][300]) + "
" + String(myLanguage[language][288]) + "
"; + html += ""; + + webserver.send(200, "text/html", html); +} + +void handleDownloadCSV() { + // Attempt to open the CSV file from SPIFFS in read mode + fs::File file = SPIFFS.open("/logbook.csv", "r"); + + // Check if the file was successfully opened + if (!file) { + // If the file could not be opened, send an error response + webserver.send(500, "text/plain", "Failed to open logbook for download"); + return; // Exit the function if the file cannot be opened + } + + // Set the headers to specify that the response will be a CSV file for download + webserver.sendHeader("Content-Type", "text/csv"); // Set MIME type for CSV files + webserver.sendHeader("Content-Disposition", "attachment; filename=logbook.csv"); // Suggests the file name for download + + // Stream the CSV file content directly to the browser + webserver.streamFile(file, "text/csv"); + + // Close the file after streaming the content to release resources + file.close(); +} + +bool handleCreateNewLogbook() { + // Check if the file "logbook.csv" already exists + if (SPIFFS.exists("/logbook.csv")) { + // If it exists, delete the file + if (!SPIFFS.remove("/logbook.csv")) { + // Return false if the file could not be deleted + return false; + } + } + + // Create a new "logbook.csv" file in write mode + fs::File file = SPIFFS.open("/logbook.csv", "w"); + + // Check if the file was successfully created + if (!file) { + // Return false if file creation fails + return false; + } + + // Write the header to the new CSV file + String header = "Date,Time,Frequency,PI code,Signal,Stereo,TA,TP,PTY,PS,RadioText\n"; + file.print(header); // Ensure that the header is written properly + + // Make sure the data is written before closing the file + file.flush(); // Ensure that everything is written to the file + file.close(); // Close the file after writing + + + logcounter = 0; // Reset logcounter + EEPROM.writeUInt(EE_UINT16_LOGCOUNTER, logcounter); + EEPROM.commit(); + // Return true if the function runs without problems + return true; +} + +byte addRowToCSV() { + // Ensure there is at least 150 bytes of free space in SPIFFS before proceeding + if (SPIFFS.totalBytes() - SPIFFS.usedBytes() < 150 || logcounter > 1000) { + return 2; // Return 2 if insufficient free space is available + } + + // 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 1; // Return 1 if the file cannot be opened + } + + // Fetch the current date and time as a string + String currentDateTime = getCurrentDateTime(); + + // Use a placeholder ("-,-") if the date and time could not be retrieved + if (currentDateTime == "") { + currentDateTime = "-,-"; + } + + // 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"; + + // Calculate signal strength based on the selected unit + int SStatusprint = 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 + + // 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"; + else if (unit == 1) signal += " dBf"; + else if (unit == 2) signal += " dBm"; + + // 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 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 + + // Handle PTY, TA, TP and Stereo flag + String TA; + String TP; + String Stereo; + String pty; + if (radio.rds.hasTA) TA = "•"; else TA = ""; + if (radio.rds.hasTP) TP = "•"; else TP = ""; + if (radio.getStereoStatus()) Stereo = "•"; else Stereo = ""; + pty = String(radio.rds.stationTypeCode); + + // Construct the CSV row data + String row = currentDateTime + "," + + frequencyFormatted + "," + + radio.rds.picode + "," + + signal + "," + + Stereo + "," + + TA + "," + + TP + "," + + pty + "," + + stationName + "," + + radioTextModified + "\n"; + + // Write the row to the file and close it + if (file.print(row)) { + file.close(); // Successfully wrote to the file + logcounter++; + EEPROM.writeUInt(EE_UINT16_LOGCOUNTER, logcounter); + EEPROM.commit(); + return 0; // Return 0 to indicate success + } else { + file.close(); // Close the file if writing fails + return 1; // Return 1 to indicate failure + } +} + +String getCurrentDateTime() { + // Check if the RTC has been set + if (!rtcset) { + return "-,-"; // Return placeholder when the RTC is not set + } + + // Use the ESP32's time functions to retrieve the current time + struct tm timeInfo; + if (!getLocalTime(&timeInfo)) { + return "-,-"; // Return placeholder if local time is unavailable + } + + // Adjust timeInfo using the GMT offset + time_t currentEpoch = mktime(&timeInfo); // Convert struct tm to time_t format + + // Calculate GMT offset + currentEpoch += (NTPupdated ? NTPoffset * 3600 : radio.rds.offset); // Apply GMT offset if NTPupdated, else RDS offset + + // Apply DST adjustment if NTPupdated and autoDST are true + if (NTPupdated && autoDST) { + struct tm tempTimeInfo; + localtime_r(¤tEpoch, &tempTimeInfo); // Convert to struct tm for DST calculation + if (isDST(mktime(&tempTimeInfo))) { // Check if DST is in effect + currentEpoch += 3600; // Add 1-hour DST offset + } + } + + // Convert adjusted time back to struct tm format + localtime_r(¤tEpoch, &timeInfo); + + // Buffer for formatted date-time string + char buf[20]; + + if (clockampm) { + // USA format: MM/DD/YYYY, HH:MM:SS AM/PM + strftime(buf, sizeof(buf), "%m/%d/%Y", &timeInfo); // Format as MM/DD/YYYY + + // Format time in 12-hour format with AM/PM + int hour = timeInfo.tm_hour; + String ampm = (hour >= 12) ? "PM" : "AM"; // Determine AM or PM + if (hour == 0) hour = 12; // Convert 0 hour to 12 AM + else if (hour > 12) hour -= 12; // Convert to 12-hour format for PM + + String timeWithAMPM = String(hour) + ":" + (timeInfo.tm_min < 10 ? "0" : "") + String(timeInfo.tm_min) + ":" + (timeInfo.tm_sec < 10 ? "0" : "") + String(timeInfo.tm_sec) + " " + ampm; + + // Return the final formatted date and time for the USA region + return String(buf) + "," + timeWithAMPM; + } else { + // European format: DD-MM-YYYY, HH:MM:SS + strftime(buf, sizeof(buf), "%d-%m-%Y", &timeInfo); // Format as DD-MM-YYYY + String timeEuropean = String(timeInfo.tm_hour) + ":" + (timeInfo.tm_min < 10 ? "0" : "") + String(timeInfo.tm_min) + ":" + (timeInfo.tm_sec < 10 ? "0" : "") + String(timeInfo.tm_sec); // Format time with leading zero if needed + return String(buf) + "," + timeEuropean; + } +} + +bool isDST(time_t t) { + struct tm timeInfo; + localtime_r(&t, &timeInfo); // Convert time_t to struct tm + + int month = timeInfo.tm_mon + 1; // tm_mon is 0-based, so add 1 + int day = timeInfo.tm_mday; // tm_mday is the day of the month + int hour = timeInfo.tm_hour; // tm_hour is the hour of the day + int weekday = timeInfo.tm_wday; // tm_wday is the day of the week (0 = Sunday) + + // DST starts last Sunday in March at 2:00 AM + if (month == 3) { + int lastSunday = 31 - ((weekday + 31 - day) % 7); + if (day > lastSunday || (day == lastSunday && hour >= 2)) { + return true; + } + } + + // DST ends last Sunday in October at 3:00 AM + if (month == 10) { + int lastSunday = 31 - ((weekday + 31 - day) % 7); + if (day < lastSunday || (day == lastSunday && hour < 3)) { + return false; + } + } + + // DST is active from April to September + if (month > 3 && month < 10) { + return true; + } + + return false; +} + +void handleLogo() { + fs::File file = SPIFFS.open("/logo.png", "r"); + if (!file) { + webserver.send(404, "text/plain", "Logo not found"); + return; + } + webserver.streamFile(file, "image/png"); + file.close(); +} + +void printLogbookCSV() { + // Attempt to open the CSV file stored in SPIFFS + fs::File file = SPIFFS.open("/logbook.csv", "r"); + + // Check if the file was successfully opened + if (!file) { + Serial.println("Failed to open logbook!"); + return; + } + + // Print a message indicating the start of the file content + Serial.println("===== Start of logbook.csv ====="); + + // Read and print the contents of the file line by line + while (file.available()) { + String line = file.readStringUntil('\n'); // Read one line at a time + Serial.println(line); // Print the line to the Serial Monitor + } + + // Close the file after reading + file.close(); + + // Print a message indicating the end of the file content + Serial.println("===== End of logbook.csv ====="); +} \ No newline at end of file diff --git a/src/logbook.h b/src/logbook.h new file mode 100644 index 0000000..75bd5f7 --- /dev/null +++ b/src/logbook.h @@ -0,0 +1,35 @@ +#ifndef LOGBOOK_H +#define LOGBOOK_H + +#include +#include +#include +#include +#include +#include "TEF6686.h" + +extern bool autoDST; +extern bool clockampm; +extern bool NTPupdated; +extern bool rtcset; +extern byte language; +extern byte unit; +extern int16_t SStatus; +extern int8_t NTPoffset; +extern unsigned int ConverterSet; +extern unsigned int frequency; +extern unsigned int logcounter; + +extern TEF6686 radio; +extern WebServer webserver; + +void handleRoot(); +void handleDownloadCSV(); +bool handleCreateNewLogbook(); +byte addRowToCSV(); +String getCurrentDateTime(); +bool isDST(time_t t); +void handleLogo(); +void printLogbookCSV(); + +#endif \ No newline at end of file