#include "csv_writer.h" #include "web_config.h" #include "ntp.h" #include "led_effects.h" #include "sensor_console.h" namespace csv_writer { unsigned long last_written_at = 0; char last_successful_write[23]; #if defined(ESP8266) /** * SPECIFIC FUNCTIONS FOR LITTLEFS */ FSInfo fs_info; bool mountFS() { return LittleFS.begin(); // format if needed. } void updateFsInfo() { FS_LIB.info(fs_info); } int getTotalSpace() { return fs_info.totalBytes; } int getUsedSpace() { return fs_info.usedBytes; } void showFilesystemContent() { Dir dir = FS_LIB.openDir("/"); while (dir.next()) { Serial.print(" "); Serial.print(dir.fileName()); Serial.print(" - "); if (dir.fileSize()) { File f = dir.openFile("r"); Serial.println(f.size()); f.close(); } else { Serial.println("0"); } } } #elif defined(ESP32) /** * SPECIFIC FUNCTIONS FOR SPIFFS */ bool mountFS() { return SPIFFS.begin(true); // format if needed. } void updateFsInfo() { // Nothing to do. } int getTotalSpace() { return SPIFFS.totalBytes(); } int getUsedSpace() { return SPIFFS.usedBytes(); } void showFilesystemContent() { File root = SPIFFS.open("/"); File file = root.openNextFile(); while (file) { Serial.print(" "); Serial.print(file.name()); Serial.print(" - "); Serial.println(file.size()); file = root.openNextFile(); } } #endif char filename[20]; // e.g. "/ESPxxxxxx.csv\0" int getAvailableSpace() { return getTotalSpace() - getUsedSpace(); } void initialize(const char *basename) { snprintf(filename, sizeof(filename), "/%.14s.csv", basename); Serial.println(); Serial.print(F("Initializing FS...")); if (mountFS()) { Serial.println(F("done.")); } else { Serial.println(F("fail.")); return; } updateFsInfo(); Serial.println(F("File system info:")); Serial.print(F(" Total space : ")); Serial.print(getTotalSpace() / 1024); Serial.println("kB"); Serial.print(F(" Used space : ")); Serial.print(getUsedSpace() / 1024); Serial.println("kB"); Serial.print(F(" Available space: ")); Serial.print(getAvailableSpace() / 1024); Serial.println("kB"); Serial.println(); // Open dir folder Serial.println(F("Filesystem content:")); showFilesystemContent(); Serial.println(); sensor_console::defineIntCommand("csv", setCSVinterval, F("60 (Sets CSV writing interval, in s)")); sensor_console::defineCommand("format_filesystem", formatFilesystem, F("(Deletes the whole filesystem)")); sensor_console::defineCommand("show_csv", showCSVContent, F("(Displays the complete CSV file on Serial)")); } File openOrCreate() { File csv_file; if (FS_LIB.exists(filename)) { csv_file = FS_LIB.open(filename, "a+"); } else { csv_file = FS_LIB.open(filename, "w"); csv_file.print(F("Sensor time;CO2 concentration\r\n")); csv_file.print(F("YYYY-MM-DD HH:MM:SS+ZZ;ppm\r\n")); } return csv_file; } void log(const char *timestamp, const int16_t &co2, const float &temperature, const float &humidity) { led_effects::onBoardLEDOn(); File csv_file = openOrCreate(); char csv_line[42]; snprintf(csv_line, sizeof(csv_line), "%s;%d\r\n", timestamp, co2); if (csv_file) { size_t written_bytes = csv_file.print(csv_line); csv_file.close(); if (written_bytes == 0) { Serial.println(F("Nothing written. Disk full?")); } else { Serial.print(F("CSV - Wrote : ")); Serial.print(csv_line); ntp::getLocalTime(last_successful_write); } updateFsInfo(); delay(50); } else { //NOTE: Can it ever happen that outfile is false? Serial.println(F("Problem on create file!")); } led_effects::onBoardLEDOff(); } void logIfTimeHasCome(const char *timeStamp, const int16_t &co2, const float &temperature, const float &humidity) { unsigned long now = seconds(); if (now - last_written_at > config::csv_interval) { last_written_at = now; log(timeStamp, co2, temperature, humidity); } } /***************************************************************** * Callbacks for sensor commands * *****************************************************************/ void setCSVinterval(int32_t csv_interval) { config::csv_interval = csv_interval; Serial.print(F("Setting CSV Interval to : ")); Serial.print(config::csv_interval); Serial.println("s."); led_effects::showKITTWheel(color::green, 1); } void showCSVContent() { //TODO: Now that ampel_name can be set, should show the content of every csv Serial.print(F("### ")); Serial.print(filename); Serial.println(F(" ###")); File csv_file; if (FS_LIB.exists(filename)) { csv_file = FS_LIB.open(filename, "r"); while (csv_file.available()) { Serial.write(csv_file.read()); } csv_file.close(); } Serial.println(F("######################")); } void formatFilesystem() { FS_LIB.format(); led_effects::showKITTWheel(color::blue, 2); } }