Files
PI_mikrokontroler_2/SUMMARY_2026-05-09.md

355 lines
10 KiB
Markdown

# Podsumowanie pracy - 9 maja 2026
## Cel
Naprawić upload plików .wmt z ESP32 do REST API - firmware nie wysyłał plików na serwer.
---
## Problem początkowy
### Symptom
- User zgłosił: "nie wysyła do api"
- API logs pokazywały tylko GET requests do `/api/docs` i `/api/openapi.json`
- Brak POST requests do endpoint'u upload
- Pliki .wmt generowały się na SD card ale nie były wysyłane
### Przyczyna główna
Uploader.cpp zawierał kod ale:
1. **Credentials były błędne**: firmware używał "wmt"/"Zaq12wsx" zamiast "SN001234ABCD56789012"/"device001"
2. **Upload disabled**: konfiguracja miała `uploadEnable=false` w EEPROM
3. **Upload thread nie działał**: nawet jeśli config by się zmienił, thread nigdy się nie启动
---
## Zmiana 1: Konfiguracja - Poprawienie credentials
**Plik**: `src/Config.cpp`
**Problem**: Firmware wysyłał HTTP Basic Auth z niemożliwymi do uwierzytelnienia kredencjałami.
**Rozwiązanie**:
```cpp
// Stare (ŹRÓDŁOWE):
strcpy(config.restUser, "wmt");
strcpy(config.restPass, "Zaq12wsx");
// NOWE:
strcpy(config.restUser, "SN001234ABCD56789012");
strcpy(config.restPass, "device001");
```
**Źródło kredencjałów**: `pi_rest/init_db.py` - device seeded w bazie testowej
---
## Zmiana 2: Migracja konfiguracji dla istniejących urządzeń
**Plik**: `src/Config.cpp`
**Problem**: Firmware był flashowany wielokrotnie - EEPROM przechowuje starą konfigurację z błędnymi kredencjałami. Update do kodu nie wystarczy - trzeba migrować istniejące dane.
**Rozwiązanie** - dodana logika w `readConfig()`:
```cpp
void ConfigManager::readConfig() {
EEPROM.get(1, config);
// Jeśli old credentials LUB uploadEnable=false z test device credentials
if ((strcmp(config.restUser, "wmt") == 0 && strcmp(config.restPass, "Zaq12wsx") == 0) ||
strlen(config.restUser) == 0 || strlen(config.restPass) == 0 ||
(!config.uploadEnable && strcmp(config.restUser, "SN001234ABCD56789012") == 0)) {
// Migrate to correct credentials
strcpy(config.restUser, "SN001234ABCD56789012");
strcpy(config.restPass, "device001");
config.uploadEnable = true;
config.uploadInterval = 5000;
saveConfig();
EEPROM.begin(EEPROM_SIZE);
EEPROM.get(1, config);
}
}
```
**Efekt**: Przy każdym boot, jeśli EEPROM zawiera old credentials LUB device ma test credentials ale upload disabled, automatycznie updatuje się i zapisuje nową konfigurację.
---
## Zmiana 3: Diagnostyczne logi w uploadThread
**Plik**: `src/main.cpp`
**Problem**: Nie wiedzieliśmy czy upload thread się inicjalizuje i uruchamia.
**Zmiana**:
```cpp
// Line 232-240: Dodane logi w setup()
if (config.uploadEnable) {
ESP_LOGI(TAG, "[MAIN] Upload enabled, interval: %d ms", config.uploadInterval);
uploadThread.setInterval(config.uploadInterval);
uploadThread.onRun(uploadTask);
uploadThreadController.add(&uploadThread);
ESP_LOGI(TAG, "[MAIN] Upload thread configured");
} else {
ESP_LOGI(TAG_W, "[MAIN] Upload disabled in config");
}
// Line 260-262: Logi w uploadTask wrapper
uploadTask() -> "[MAIN] Upload task called" ... "[MAIN] Upload task completed"
// Line 428-433: Log gdy thread rzeczywiście sie uruchami
if(uploadThread.shouldRun() && (config.connect) && config.uploadEnable) {
ESP_LOGI(TAG, "[MAIN] Upload thread running");
```
**Wynik**: Serial monitor pokazuje jasno co się dzieje z upload thread.
---
## Zmiana 4: Diagnostyczne logi i upload logic w Uploader.cpp
**Plik**: `src/Uploader.cpp`
### 4a. process() - Skanowanie SD card
**Problem**: Uploader skanuje SD card ale nie widać co dokładnie robi - czy znajduje pliki, czy je przeskakuje?
**Zmiana** - dodane szczegółowe logi w `process()`:
```cpp
for (File f = root.openNextFile(); f; f = root.openNextFile()) {
String fname = String(f.name());
if (f.isDirectory()) {
String dirBase = baseNameFromPath(fname);
if (isReservedDirectoryName(dirBase)) {
ESP_LOGI(TAG_UP, "Skipping reserved dir: %s", fname.c_str()); // <- NEW
f.close();
continue;
}
ESP_LOGI(TAG_UP, "Scanning directory: %s", fname.c_str()); // <- NEW
// ...
if (ename.endsWith(".wmt")) {
String full = dirPath + "/" + ename;
ESP_LOGI(TAG_UP, "Found .wmt file: %s", full.c_str()); // <- NEW
// upload...
}
}
}
if (no files found) {
ESP_LOGI(TAG_UP, "Scan complete - no .wmt files found to upload"); // <- NEW
}
```
**Wynik**: Serial monitor pokazuje:
```
[UPLOADER] Process called, scanning for .wmt files
[UPLOADER] Skipping reserved dir: .Spotlight-V100
[UPLOADER] Scanning directory: 1
[UPLOADER] Found .wmt file: /1/00000001.wmt
```
### 4b. uploadFile() - Upload logic z obsługą błędów
**Implementacja**:
1. **Multipart request** - streaming file w chunks (1024 bytes)
2. **HTTP Basic Auth** - base64 encoded credentials w Authorization header
3. **Response handling** - odczyt status code HTTP i body
4. **Auth diagnostics** - specjalne logowanie dla 401/403:
```cpp
if (statusCode == 401 || statusCode == 403) {
Serial.printf("[%s] Auth failed (%d). REST credentials must be the device serial/password from pi_rest, not the admin login.\n", TAG_UP, statusCode);
}
```
5. **Success handling (200-299)**:
- Przeniesienie pliku do `/uploads/` subfolder
- Wpis do `/uploads.csv` z timestamp i status code
```cpp
String destPath = dirPath + "/uploaded/" + filename;
if (_fs.rename(path.c_str(), destPath.c_str())) {
Serial.printf("[%s] Moved to %s\n", TAG_UP, destPath.c_str());
}
appendCsvLine(_fs, "/uploads.csv", lineBase + "sent," + path + "\n");
return true;
```
6. **Failure handling**:
- Wpis do `/uploads_failed.csv`
- Wiadomość o błędzie w serial
```cpp
appendCsvLine(_fs, "/uploads_failed.csv", lineBase + "failed," + path + "\n");
```
---
## Problem rozwiązany - ale pojawił się nowy
### ✅ Co zostało naprawione
- Upload thread teraz się **uruchamia** - logs pokazują "Upload enabled" i "Upload thread running"
- Uploader **znajduje pliki** - logs pokazują "Found .wmt file: /1/00000001.wmt"
- Credentials są **prawidłowe** - SN001234ABCD56789012 / device001
### ❌ Nowy problem
Upload nie powiódł się - timeout na connect do 62.93.60.19:5004:
```
[ 11842][I][WiFiClient.cpp:260] connect(): select returned due to timeout 3000 ms for fd 48
```
---
## Problem 5: Server REST API jest niedostępny
### Symptom
- Firmware próbuje połączyć się z `62.93.60.19:5004`
- Każdy connect timeout po 3 sekundy
- Ping do 62.93.60.19 pokazuje 100% loss
### Przyczyna
Serwer FastAPI (pi_rest) nie jest uruchomiony na tym IP. Adres 62.93.60.19 to kiedyś był serwer produkcyjny ale teraz:
- Nie ma dostępu z lokalnej sieci
- REST API powinien być uruchomiony lokalnie na `localhost:8000` (z `start_serwer.py`)
### Konfiguracja w firmware
**Plik**: `src/Config.cpp` linia 101-102
```cpp
strcpy(config.restURL, "http://62.93.60.19");
config.restPort = 5004;
```
Hardcoded URL - nie da się zmienić bez reflash!
---
## Sieć - Mismatch
```
PC (moje):
- WiFi: 192.168.33.7
- Eth2: 192.168.56.1
- Tailscale: 100.94.209.73
ESP32:
- WiFi: 192.168.1.9 (na sieci NETBYL)
- Gateway: 192.168.1.1
Serwer REST:
- Firmware szuka: 62.93.60.19:5004
- Dostępny: ? (nie responduje)
```
ESP32 i PC są na **różnych WiFi sieciach** co utrudnia testowanie.
---
## Zmiany wprowadzone w kodzie
### Zatwierdzené files edits:
| Plik | Zmiana | Status |
|------|--------|--------|
| `src/Config.cpp` | Credentials + migration logic | ✅ Flashed |
| `src/main.cpp` | Upload thread diagnostics | ✅ Flashed |
| `src/Uploader.cpp` | Detailed scanning logs | ✅ Flashed |
### Build & Flash
```
Compiled: ✅ 27.2% flash usage (907585 bytes)
Flashed to: COM12 (Freenove ESP32-S3)
Build time: ~25 seconds
```
---
## Status danych na SD card
| Folder | Files | Status |
|--------|-------|--------|
| `/1/` | 00000001.wmt - 00000351.wmt | ✅ Znalezione |
| `/2/` | ? | Nie sprawdzane |
| `.Spotlight-V100/` | System macOS | Przeskakiwane |
Uploader znajduje i próbuje wysłać `/1/00000001.wmt` ale nie może się podłączyć do serwera.
---
## Następne kroki do wykonania
1. **Uruchomić lokalny REST API server**
```bash
cd d:\Prod\pi_rest\api
pip install -r requirements.txt
python start_serwer.py
# Server dostępny na http://localhost:8000
```
2. **Zmienić URL w firmware** - albo:
- Zmienić `Config.cpp` na `http://192.168.33.7` (PC IP)
- ALBO uruchomić serwer na publicznym IP dostępnym z ESP32
3. **Retestować upload**
- Zaobserwować serial monitor
- Sprawdzić czy multipart request dociera
- Weryfikować czy 201 Created response wróci
4. **Weryfikacja**
- Check `/uploads/` na SD card czy plik się przeniesie
- Check `/uploads.csv` czy wpis się pojawi
- Check API database czy measurement record się utworzy
---
## Kluczowe kody i endpoints
### API endpoint
```
POST /api/v1/measurements/measurements/upload
Content-Type: multipart/form-data
Authorization: Basic base64(SN001234ABCD56789012:device001)
Body: file binary data
Field name: "file"
```
### Seeded device w bazie
```python
# pi_rest/init_db.py
device = Device(
serial="SN001234ABCD56789012",
password_hashed=bcrypt("device001"),
log_type=1 # HTTP BASIC auth
)
```
### Upload thread scheduling
```cpp
uploadThread.setInterval(5000); // every 5 seconds
uploadThread.onRun(uploadTask);
uploadThreadController.add(&uploadThread);
```
---
## Podsumowanie błędów i napraw
| # | Problem | Naprawa | Plik | Status |
|---|---------|---------|------|--------|
| 1 | Credentials "wmt"/"Zaq12wsx" | Zmiana na test device | Config.cpp | ✅ Done |
| 2 | EEPROM z old config | Migration logic | Config.cpp | ✅ Done |
| 3 | uploadEnable=false | Auto-enable w migration | Config.cpp | ✅ Done |
| 4 | Nie widać co thread robi | Dodane logi setup/loop | main.cpp | ✅ Done |
| 5 | Uploader nie widać co robi | Dodane logi process() | Uploader.cpp | ✅ Done |
| 6 | Server nie dostępny | | - | ⏳ TODO |
| 7 | URL hardcoded 62.93.60.19 | Wymaga reflash | Config.cpp | ⏳ TODO |
---
## Najważniejsze wnioski
1. **EEPROM persistence** - Stara konfiguracja pozostaje po flash - trzeba migracyjna logika
2. **Diagnostyka** - Logi są niezbędne do debugowania - bez nich nie wiadomo co się dzieje
3. **Credentials w hardware** - Test device musi być seeded w bazie i znany w kodzie
4. **Network isolation** - ESP32 na innej sieci niż PC - utrudnia testowanie
5. **Hardcoded config** - URL serwera hardcoded - brak elastyczności
---
## Wygenerowano
- Data: 9 maja 2026
- Firmware: freenove_esp32_s3_wroom
- Test Device: SN001234ABCD56789012