Add comprehensive filesystem error detection and handling:
- SPIFFS: Check free space before writes, fail with ESP_ERR_STORAGE_FULL if <25KB (~5%)
- SD Card: Check free space before writes, fail with ESP_ERR_STORAGE_FULL if <10MB
- Mount state: Log actionable errors on first occurrence when backends unavailable
- Error recovery: Reset warning state when space recovers above 2x threshold
API changes:
- storage_info_t: Add spiffs_mounted, spiffs_error, sd_error fields
- storage_error_state_t enum: ok, not_mounted, full, io_error, corrupt
- REST API /api/logs: Add nested spiffs{} and sd{} objects with error states
Integration:
- history_cache_record(): SPIFFS space check before writes
- storage_data_logger_record(): SD space check before daily file writes
- storage_get_info(): Populate new error state fields
- status_led: Set LED_PATTERN_WARNING on storage errors
- error_log: Add actionable messages ("SPIFFS full - reduce probe count")
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add robust checksum validation for multi-controller state sync:
- Return ESP_ERR_INVALID_CRC error on checksum mismatch (in strict mode)
- Automatically request full snapshot from leader on checksum failure
- Add configurable validation strictness via CONFIG_CONTROLLER_SYNC_STRICT_CHECKSUM
- Log checksum failures to persistent error log for diagnostics
- Add retry counter to prevent infinite snapshot request loops (max 3 retries)
- Emit CLEARGROW_EVENT_SYNC_CHECKSUM_FAILED event for monitoring
Implementation details:
- New handle_checksum_failure() function centralizes recovery logic
- Default permissive mode logs warnings but allows sync to proceed
- Strict mode rejects mismatched syncs and triggers automatic recovery
- Event data includes checksum values, retry count, and recovery status
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Production builds now reject HTTP configuration for security:
- network_api_start_server() returns ESP_ERR_INVALID_ARG if http_port > 0
when CONFIG_NETWORK_API_PRODUCTION_MODE is enabled
- Development mode logs detailed security warnings about HTTP usage
- Improved warning messages when HTTP enabled with secure boot
- Updated Kconfig documentation to clarify production mode behavior
This prevents accidental exposure of API keys, JWT tokens, and sensor
data over unencrypted HTTP connections in production environments.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add stack high-water mark logging to WiFi/IP event handlers (DEBUG level)
- Document coexistence findings: BLE not used, Thread uses external RCP
- Document event handler stack safety: ~1200-1500 bytes worst case,
3584 bytes available (>50% margin)
- Clarify wifi_manager uses event-driven pattern (no dedicated task)
Stack monitoring:
- log_event_handler_stack() called after disconnect and got_ip handling
- Rate-limited to avoid spam (30s interval)
- Warns if usage exceeds 70% of event loop stack
Analysis (CG-51):
- Coexistence NOT required: provisioning uses SoftAP, not BLE
- Event handler stack is safe with >50% margin
- Current event-driven architecture is appropriate
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add error checking for gpio_hold_en()/gpio_hold_dis() return values with
warnings logged on failure. Add CONFIG_CLEARGROW_PM_GPIO_HOLD option
(default y) to enable/disable GPIO hold for testing wake-from-sleep.
Document which peripherals require GPIO hold vs ESP-IDF driver handling:
- REQUIRED: SD_CS, RCP_RESET (must hold to prevent glitches)
- RECOMMENDED: LCD_BACKLIGHT (LEDC preserves, but hold is safer)
- NOT REQUIRED: Touch I2C (driver reinits, but hold prevents corruption)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add missing CLEARGROW_EVENT_PAIRING_RETRY and CLEARGROW_EVENT_PAIRING_SKIP_RETRY
events and pairing_retry_event_data_t structure to the common component's
app_events.h header file.
The retry logic implementation in code_pairing.c includes app_events.h from
common (via thread_manager's REQUIRES dependency), but the new retry events
were only added to main/app_events.h. This caused a build failure because
the types and event IDs were undefined.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements automatic retry mechanism when probe pairing times out:
- Add CONFIG_CODE_PAIRING_MAX_RETRIES (default: 2) to Kconfig
- Add retry_count, max_retries, skip_retry fields to pairing_state_t
- Modify code_pairing_handle_timeout() to retry before failing
- Preserve PSKd across retries via NVS persistence
- Add CLEARGROW_EVENT_PAIRING_RETRY event for UI notifications
- Add code_pairing_skip_retry() and code_pairing_get_retry_info() APIs
- Update scr_pairing_progress.c with retry status display
- Add Skip Retry button for users to abort retries early
- Add comprehensive unit tests for retry logic
User experience improvements:
- Pairing now automatically retries up to 2 times (3 total attempts)
- Progress screen shows "Attempt X of Y" during retries
- Skip Retry button allows early abort of remaining retries
- PSKd preserved - no need to re-enter code on retry
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add THREAD_RCP_MIN_VERSION constants to thread_br.h (1.3.0)
- Implement rcp_version_check() function to validate RCP firmware version
- Return ESP_ERR_NOT_SUPPORTED if RCP version is incompatible
- Log version comparison and error details at initialization
- Add error_log entry for version mismatch for user visibility
- Document version requirements in CLAUDE.md
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add calibration verification logging to help diagnose touch panel
configuration issues:
- Log first 5 touch coordinates at INFO level after initialization
- Display expected coordinate ranges (0-799 X, 0-479 Y)
- Warn if calibration touches exceed expected ranges
Add runtime coordinate validation:
- Track total touches and out-of-range count
- Log warning if >5% of touches are out-of-range
- Includes guidance to check swap_xy/mirror_x/mirror_y flags
This helps diagnose touch mapping issues without requiring
manual testing or a dedicated calibration utility.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move watchdog initialization before NVS to provide watchdog coverage
during NVS initialization, which can rarely hang due to flash corruption
or hardware faults.
Changes:
- Add watchdog_enable_boot_loop_detection() function that defers
NVS-based persistent reset count tracking until after NVS is ready
- Move watchdog_init() to before init_nvs() in app_main.c
- Call watchdog_enable_boot_loop_detection() immediately after NVS init
- Update watchdog.h documentation with two-tier boot loop detection:
1. RTC memory (immediate, no NVS dependency)
2. NVS-based (persistent, requires NVS)
The RTC-based boot loop detection using RTC_NOINIT_ATTR memory works
immediately without NVS, providing coverage during early boot. The
NVS-based tracking is supplementary for persistent stats across power
cycles.
Initialization order is now:
1. status_led_init() // No dependencies
2. watchdog_init(&config) // RTC-based detection active
3. init_nvs() // Now protected by watchdog
4. watchdog_enable_boot_loop_detection() // Enable NVS-based tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Check return value of save_to_nvs() in error_log_add()
- Set nvs_write_failed flag when NVS persistence fails
- Log warning message when persistence fails
- Update status LED to indicate degraded error logging
- Add error_log_get_status() API to expose persistence state
- Add error_log_status_t structure with nvs_persistence_ok and entries_in_ram
- Add error_log_nvs_ok field to scr_health_data_t for UI display
- Display warning in System Health > Errors screen when NVS persistence fails
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- ESP-IDF v5.3 Docker image for building
- Builds on push, PR, and tag events
- Uploads firmware binaries to Gitea releases on tags
- Includes bootloader, partition table, and ELF with debug symbols
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Migrating from TeamCity to Woodpecker CI. Pipeline:
- Triggers on push and pull requests
- Uses espressif/idf:v5.3 Docker image
- Builds ESP32-S3 target with parallel jobs
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add documentation explaining that the trans_timeouts statistic in
spi_bus_stats_t is not applicable to SD card operations because
the SD card uses the sdspi driver which manages its own transactions.
This counter is reserved for future devices (NFC, external display)
that will use spi_bus_transmit_timeout() for direct SPI access.
Changes:
- Add detailed doc comment to trans_timeouts field in header
- Add explanatory comment in spi_bus_log_stats()
- Add debug log line showing "N/A for SD-only config" when 0
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The previous commit added OTA manager API calls to network_api.c but
forgot to add the ota_manager component to the CMakeLists.txt REQUIRES
list, causing build failures.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive downgrade detection and handling to prevent security
vulnerabilities from being unknowingly reintroduced:
- Document downgrade policy in ota_manager.h header comments
- Add ota_downgrade_reason_t enum for classifying downgrade type
- Add is_downgrade and downgrade_reason fields to ota_update_info_t
- Add downgrade_attempts counter to ota_stats_t for monitoring
- Log all downgrade attempts at WARNING level with version details
- Update REST API /api/ota to include downgrade status in response
- Require confirm_downgrade=true in /api/ota/start for downgrades
- Add UI confirmation dialog for downgrades (destructive button style)
- Block downgrades by default when allow_downgrade=false
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
network_api.c includes watchdog.h but watchdog was missing from
CMakeLists.txt dependencies.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move automation from PRIV_REQUIRES to REQUIRES in ui component.
This ensures proper linker ordering for alert_history_* functions
called from cg_state.c.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add esp_pm_dump_locks() logging to watchdog monitor task every 60s
- Add log_pm_stats() function to display CPU frequency and PM lock status
- Add watchdog_pm_stats_t struct and watchdog_get_pm_stats() API
- Add power management metrics to /api/status REST endpoint
- Add PM stats unit tests (null param, valid data, frequency range)
Changes:
- components/watchdog/src/watchdog.c: Add PM stats logging and API
- components/watchdog/include/watchdog.h: Add watchdog_pm_stats_t type
- components/network_api/src/network_api.c: Add power section to /api/status
- test/unit/test_watchdog.c: Add PM stats test cases
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move FreeRTOS task creation from app_main.c into thread_manager component
for better encapsulation. The component now owns its complete task lifecycle.
Changes:
- Add thread_br_start_task() to create task with correct parameters
- Define task constants in header (stack=10240, priority=5, core=0)
- Add stack high-water mark monitoring for health tracking
- Document task parameters in thread_br.h
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The automation and ui components have a circular dependency:
- ui calls alert_history_* from automation
- automation calls cg_state_* from ui
Adding WHOLE_ARCHIVE ensures all symbols from the automation library
are included regardless of link order, fixing undefined reference errors.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The lv_font_montserrat_12 font is not enabled in sdkconfig, causing
CI build failures. Using montserrat_14 which is already enabled.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The previous fix missed the duplicate list item code in cg_components_input.c.
The create_list_item_base function allocates cg_list_item_data_t but did not
register a LV_EVENT_DELETE handler to free it when the object is deleted.
This adds:
- list_item_delete_cb function to free user data
- Registration of delete handler in create_list_item_base
This completes the memory leak fix for all UI components with allocated user data.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add Alert History API documentation to CLAUDE.md:
- New Key APIs section with full usage examples
- Update Component Structure to mention alert history
- Update Memory Map to include alert history in SPIFFS
- Add Alert History to Heap Usage table (~32KB)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
No documentation updates needed - the wifi_scan task was already
documented in CLAUDE.md with the implementation commit.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add wifi_scan task to Component-Managed Tasks table in CLAUDE.md.
This task is created by wizard_backend during WiFi scanning in the
setup wizard to prevent UI blocking.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace blocking esp_wifi_scan_start() call with background task that
uses wifi_manager's non-blocking scan API.
Changes:
- Create dedicated wifi_scan_task that runs scans in background
- Use wifi_mgr_scan_start() with callback instead of blocking scan
- Add 10-second timeout for scan operations
- Add wizard_backend_cancel_scan() API for user-initiated cancellation
- Add wizard_backend_is_scanning() API to check scan state
- Clean up scan task on wizard_backend_deinit()
This prevents the UI from freezing for 3-5 seconds during WiFi scans,
allowing animated spinners and touch input to work properly.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Document new /api/alerts/history and /api/alerts/history/stats
endpoints added as part of issue #7 implementation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>