Keep ESP32 OTA reachable whatever the firmware does

- Rollback: override verifyRollbackLater() so a new OTA image stays
  pending until it ran 60 s with WiFi; any earlier restart rolls back
  (the Arduino core marked every image valid at boot before)
- Task watchdog (30 s) on loop(), paused during OTA uploads
- Crash counter in RTC memory: OTA-only window after a crash, 10 min
  safe mode (WiFi + OTA only) after 3 crashes in a row
- Restart when WiFi stays down for 10 min
- Home Assistant sensor 'FlipDot Display Firmware' with version/state
- logic/boot_policy with tests (60 tests total)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mangavalkandClaude Opus 5.5 committed 2026-10-13 01:05:06 +02:00
1 parent 683a47c055
commit ddbdf7e65f
14 files changed
+517 -42

No files matched your search

+20 -3
View File
@@ -59,11 +59,28 @@ const uint32_t NANO_RESET_PULSE = 50;
#define TIMEZONE "CET-1CEST,M3.5.0,M10.5.0/3"
#define NTP_SERVER "pool.ntp.org"
// After a crash or unexpected reset, only run OTA for this long before starting the
// main code, so a firmware that crashes at boot can still be replaced
// ---------------------------------------------------------------------------
// Keeping OTA alive (see logic/boot_policy.h and system/firmware_guard.h)
// ---------------------------------------------------------------------------
// After a crash, only run OTA for this long before starting the main code
const uint32_t OTA_PANIC_WINDOW = 15000;
// This many crashes in a row: safe mode (only WiFi and OTA) for SAFE_MODE_TIME
const uint8_t SAFE_MODE_CRASHES = 3;
const uint32_t SAFE_MODE_TIME = 10UL * 60 * 1000;
// A new OTA firmware must run this long with WiFi, or the previous firmware comes back
const uint32_t FIRMWARE_VALID_TIME = 60UL * 1000;
// Running this long without a crash clears the crash counter
const uint32_t CRASH_FREE_TIME = 5UL * 60 * 1000;
// loop() must not block longer than this, or the ESP32 restarts (counts as a crash)
const uint32_t WATCHDOG_TIMEOUT_S = 30;
// WiFi: first connection at boot, and restart when WiFi stays down this long
const uint32_t WIFI_CONNECT_TIMEOUT = 30000;
const uint32_t WIFI_RESTART_TIME = 10UL * 60 * 1000;
#define FIRMWARE_VERSION "2.1.0"
// Home Assistant device id (do not change: Home Assistant's entities are linked to it)
const uint8_t HA_DEVICE_ID[] = {0x34, 0x86, 0x5d, 0x3a, 0x08, 0x28};
#define HA_DEVICE_NAME "FlipDotDisplay"
#define HA_SOFTWARE_VERSION "2.0.0"
#define HA_SOFTWARE_VERSION FIRMWARE_VERSION