csv_writer.cpp 4.07 KiB
#include "csv_writer.h"
//TODO: Allow CSV download via USB Serial, when requested (e.g. via a Python script)
namespace config {
  // Values should be defined in config.h
  uint16_t csv_interval = CSV_INTERVAL; // [s]
namespace csv_writer {
  unsigned long last_written_at = 0;
  String last_successful_write = "";
#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 const String filename = "/" + SENSOR_ID + ".csv"; int getAvailableSpace() { return getTotalSpace() - getUsedSpace(); } void initialize() { 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("Filesystem content:"); showFilesystemContent(); if (FS_LIB.exists(filename)) { Serial.print(filename); Serial.println(" has been found."); } } 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;Temperature;Humidity\r\n")); csv_file.print(F("YYYY-MM-DD HH:MM:SS+ZZ;ppm;degC;%\r\n")); } return csv_file; } void log(const String &timeStamp, const int16_t &co2, const float &temperature, const float &humidity) { LedEffects::onBoardLEDOn(); File csv_file = openOrCreate(); char csv_line[42];
snprintf(csv_line, sizeof(csv_line), "%s;%d;%.1f;%.1f\r\n", timeStamp.c_str(), co2, temperature, humidity); 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.println(F("Wrote file content:")); Serial.print(csv_line); last_successful_write = ntp::getLocalTime(); } updateFsInfo(); delay(50); } else { //NOTE: Can it ever happen that outfile is false? Serial.println(F("Problem on create file!")); } LedEffects::onBoardLEDOff(); } void logIfTimeHasCome(const String &timeStamp, const int16_t &co2, const float &temperature, const float &humidity) { unsigned long now = seconds(); //TODO: Write average since last CSV write? if (now - last_written_at > config::csv_interval) { last_written_at = now; log(timeStamp, co2, temperature, humidity); } } }