#include <list>
#include "FS.h"
#ifdef USESPIFF
#include "SPIFFS.h"
#else
#include <SD.h>
#define CS_PIN 5
#endif
File root;
std::list<String> indexList;
std::list<String> outList;
// Drukuj wiersz CSV "CLR,CF012,TFT_GREEN,0x07E0" w kolumnach
void printRowCSV(const String& line, int wKod = 3, int wIdx = 5, int wNam = 16) {
int a = line.indexOf(',');
if (a < 0) return;
int b = line.indexOf(',', a + 1);
if (b < 0) return;
int c = line.indexOf(',', b + 1);
if (c < 0) return;
String c0 = line.substring(0, a);
c0.trim(); // KOD
String c1 = line.substring(a + 1, b);
c1.trim(); // INDEX
String c2 = line.substring(b + 1, c);
c2.trim(); // NAZWA
String c3 = line.substring(c + 1);
c3.trim(); // WARTOŚĆ
if ((int)c2.length() > wNam)
// opcjonalne przycięcie
c2.remove(wNam);
auto col = [](const String& s, int w) {
Serial.print(s);
Serial.print(", ");
int pad = w - (int)s.length();
while (pad-- > 0)
Serial.write(' ');
};
Serial.print("║ ");
col(c0, wKod);
col(c1, wIdx);
col(c2, wNam);
Serial.println(c3); // ostatnia kolumna bez przecinka
}
// Prosty listing katalogu na wybranym systemie plików (SPIFFS/SD)
void listDir(fs::FS &fs, const char * dirname) {
Serial.printf("Katalog: %s\n", dirname);
File root = fs.open(dirname);
if (!root || !root.isDirectory()) {
Serial.println("- brak katalogu");
return;
}
File file = root.openNextFile();
while (file) {
Serial.printf("- %s (%dB)\n", file.name(), file.size());
file = root.openNextFile();
}
}
void setup() {
Serial.begin(115200);
#ifdef USESPIFF
// Montowanie SPIFFS (sformatuj jeśli uszkodzony/nieistnieje)
if (!SPIFFS.begin(true)) {
Serial.println("BŁĄD: montowanie SPIFFS nie powiodło się");
return;
}
#else
// Montowanie karty SD
if (!SD.begin(CS_PIN)) {
Serial.println("BŁĄD: inicjalizacja karty SD nie powiodła się!");
while (true) ;
}
#endif
Serial.println("Inicjalizacja zakończona.\n");
// 1) Zbuduj listę indeksów z FileB.txt (druga kolumna)
createIndexList("FileB.txt");
// 2) Znajdź nowe wpisy w FileA.txt (brakujące indeksy)
evaluateFile("FileA.txt");
// 3) Zapisz różnice do FileC.txt (dopisywanie lub nadpisywanie wg trybu)
writeResultToFile("FileC.txt");
// 4) Jednorazowa weryfikacja zapisu: odczyt FileC.txt i listing roota
showFilePretty("FileC.txt");
}
void loop() {
delay(100);
// Nic nie robimy po zakończeniu setup()
}
// Budowanie listy indeksów z pliku (druga kolumna CSV)
void createIndexList(String aFile) {
indexList.clear();
String aLine = "";
#ifdef USESPIFF
File textFile = SPIFFS.open("/" + aFile);
#else
File textFile = SD.open("/" + aFile);
#endif
if (!textFile) {
Serial.println("Błąd otwierania pliku " + aFile);
return;
}
Serial.println("╔══ Lista indeksów z pliku " + aFile + " ═╗");
auto handleLine = [&](const String& line) {
String idx = stripIndex(line);
if (idx.length()) {
indexList.push_back(idx);
Serial.print("║ ");
Serial.println(idx);
}
};
while (textFile.available()) {
char c = textFile.read();
if (c >= ' ') aLine += c;
if (c == '\n' || c == '\r') {
if (aLine.length()) handleLine(aLine);
aLine = "";
}
}
if (aLine.length())
handleLine(aLine); // ostatnia linia bez \n
textFile.close();
Serial.println("╚═════════════════════════════════════╝\n");
}
// Wyciągnij indeks (druga kolumna) i dodaj do listy
void checkForIndexList(String line) {
String idx = stripIndex(line);
Serial.println(idx);
if (idx > "")
indexList.push_back(idx);
}
// Zwraca drugą kolumnę z linii CSV: "coś,INDEKS,coś"
String stripIndex(String Line) {
int c1 = Line.indexOf(',');
int c2 = Line.indexOf(',', c1 + 1);
String index = "";
if (c1 >= 0 && c2 > c1) {
index = Line.substring(c1 + 1, c2);
index.trim(); // usuń spacje/białe znaki
}
return index;
}
// Przejrzyj FileA.txt i znajdź wpisy z indeksami, których nie ma w indexList
void evaluateFile(String aFile) {
String aLine = "";
outList.clear();
#ifdef USESPIFF
File textFile = SPIFFS.open("/" + aFile);
#else
File textFile = SD.open("/" + aFile);
#endif
if (!textFile) {
Serial.println("Błąd otwierania pliku " + aFile);
return;
}
Serial.println("╔══════ Analiza pliku " + aFile + " ══════╗");
auto handleLine = [&](const String& line) {
String idx = stripIndex(line);
if (idx.length() && !indexFound(idx)) {
Serial.print("║ ");
Serial.println(idx); // pokazuj tylko indeks
outList.push_back(line); // a pełną linię zapisz do outList
}
};
while (textFile.available()) {
char c = textFile.read();
if (c >= ' ') aLine += c;
if (c == '\n' || c == '\r') {
if (aLine.length()) handleLine(aLine);
aLine = "";
}
}
if (aLine.length()) handleLine(aLine); // ostatnia linia bez \n
textFile.close();
Serial.println("╚═════════════════════════════════════╝\n");
}
// Jeśli indeks z linii nie występuje w indexList → dodaj całą linię do outList
void checkForOutList(String line) {
String idx = stripIndex(line);
if (idx > "" && !indexFound(idx)) {
Serial.println(idx);
outList.push_back(line);
}
}
// (używane, jeśli chcesz dorzucać indeks bez sprawdzania)
void checkIndex(String line) {
String idx = stripIndex(line);
if (idx > "")
indexList.push_back(idx);
}
// Sprawdzenie, czy indeks już istnieje w indexList
boolean indexFound(String aIndex) {
for (auto ix : indexList) {
if (aIndex == ix) return true;
}
return false;
}
// Zapis wyniku do pliku wyjściowego (FileC.txt)
void writeResultToFile(String wFile) {
String path = "/" + wFile;
#ifdef USESPIFF
//File tFile = SPIFFS.open(path, FILE_WRITE); // nadpis
File tFile = SPIFFS.open(path, FILE_APPEND); // dopisz na końcu
#else
File tFile = SD.open(path, FILE_WRITE);
#endif
if (!tFile) {
Serial.println("Błąd otwierania pliku " + wFile);
return;
}
Serial.println("╔═════ Zapis do pliku " + wFile + " ══════╗");
for (auto &txt : outList) {
tFile.println(txt);
printRowCSV(txt, /*wKod=*/3, /*wIdx=*/5, /*wNam=*/15);
}
tFile.close();
Serial.println("╚═════════════════════════════════════╝\n");
}
// Jednorazowa weryfikacja zapisu: odczyt FileC.txt i listing roota
void showFilePretty(String wFile) {
String path = "/" + wFile;
Serial.println(" Odczyt kontrolny pliku " + wFile);
Serial.println("╔═══════════════ Wpisy ═══════════════╗");
#ifdef USESPIFF
File r = SPIFFS.open(path, FILE_READ);
#else
File r = SD.open(path, FILE_READ);
#endif
if (r) {
String line;
auto flushLine = [&]() {
if (line.length())
printRowCSV(line, /*wKod=*/3, /*wIdx=*/5, /*wNam=*/15);
line = "";
};
while (r.available()) {
char ch = r.read();
if (ch == '\n' || ch == '\r')
flushLine();
else if (ch >= 32)
line += ch;
}
flushLine(); // ostatnia linia bez \n
r.close();
} else {
Serial.println("║ (błąd otwarcia pliku)");
}
Serial.println("╚═════════════════════════════════════╝");
#ifdef USESPIFF
listDir(SPIFFS, "/");
#else
listDir(SD, "/");
#endif
}