software/ampel-firmware/csv_writer.cpp
2021-05-09 20:45:59 +02:00

165 lines
3.9 KiB
C++

#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();
Serial.println();
}
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) {
led_effects::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.print(F("CSV - Wrote : "));
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!"));
}
led_effects::onBoardLEDOff();
}
void logIfTimeHasCome(const String &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);
}
}
}