Skip to content

Ватериус-2: OTA обновление по воздуху #363

@dontsovcmc

Description

@dontsovcmc
  1. в Ватериусе-2 применена ESP8266-12F, поэтому обновление прошивки влезет в неё.

  2. ИИшка прилетела и принесла идеи реализации:

🎯 Ключевые решения для production

  1. Двухчастевая прошивка (Firmware + SPIFFS)
    Архитектура:

text
ESP8266 4MB Flash
├─ Bootloader + RF calib (8 KB)
├─ Firmware code (U_FLASH) ← ~300-384 KB
├─ SPIFFS (U_SPIFFS) ← ~80-128 KB
├─ OTA mirror ← зеркало кода
└─ Окно OTA
Почему две части:

Код обновляется часто (логика, фиксы)

Файловая система реже (конфиги, веб-интерфейс)

Раздельные checksum для верификации целостности

Можно обновлять только нужную часть

API ответ:

json
{
"ota": {
"code": {
"url": "s3://...code.bin",
"size_bytes": 320000,
"checksum": "abc123..."
},
"spiffs": {
"url": "s3://...spiffs.bin",
"size_bytes": 100000,
"checksum": "def456..."
},
"total_checksum": "combined_hash"
}
}
2. Graceful Failure: OTA Error Tracking
На устройстве (EEPROM):

cpp
ota_errors: 0-3 // Счётчик попыток
ota_last_error: string // "TIMEOUT", "CHECKSUM_FAIL", "WRITE_FAIL" и т.д.
Flow при ошибке:

text

  1. Попытка OTA → FAIL
  2. device.ota_errors++ → сохраняем в EEPROM
  3. При следующем checkin отправляем ota_errors: 1
  4. Сервер проверяет: если >= 3 → выставляет Device.ota_disabled = true
  5. При ota_disabled сервер больше не предлагает OTA
  6. Устройство проверяет is_ota_disabled() перед OTA → пропускает
  7. Устройство продолжает работать со старой прошивкой (graceful degradation)
    На сервере:

python
Device.ota_errors = 0-3 # Синхронизируется с устройством
Device.ota_last_error = string # Для диагностики
Device.ota_last_error_timestamp # Когда произошла
Админка показывает:

text
Device "Waterius_001"
├─ ✅ OK (если ota_errors = 0)
├─ ⚠️ Errors: 2 (если 1-2)
└─ ❌ Disabled (если >= 3) → можно ручной reset
3. Таймауты для больших файлов
Проблема: Файл 400 KB загружается 10+ секунд на медленной сети

Решение:

cpp
http.setConnectTimeout(30000); // 30 сек на establish connection
http.setTimeout(60000); // 60 сек на читать между пакетами (важно!)

#define OTA_TIMEOUT_TOTAL 120000 // 2 минуты на весь процесс
#define OTA_TIMEOUT_IDLE 30000 // 30 сек без данных → abort
Оптимизация буфера:

cpp
uint8_t buff[1024]; // 1 KB вместо 256 bytes → меньше overhead на write

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions