forked from Akcelerometry_drgania_WMT/PI_mikrokontroler
Wgranie zmian do repozytorium
This commit is contained in:
354
SUMMARY_2026-05-09.md
Normal file
354
SUMMARY_2026-05-09.md
Normal file
@@ -0,0 +1,354 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user