Skip to content

fix(ota): wake for async updates - #144

Merged
ODevStudio merged 2 commits into
mainfrom
audit/pr-018-wake-elegant-ota
Aug 13, 2026
Merged

fix(ota): wake for async updates#144
ODevStudio merged 2 commits into
mainfrom
audit/pr-018-wake-elegant-ota

Conversation

@ODevStudio

@ODevStudio ODevStudio commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Wake soft-sleep hardware from the main loop whenever OTA becomes active.
  • Make b_softSleep describe applied rail state rather than an asynchronous sleep request.
  • Queue BLE and WebSocket sleep intent until the main loop performs the hardware transition.
  • Keep all rail, ADC, and OLED work out of AsyncTCP and BLE callbacks.

Root Cause

WiFi remains active during soft sleep, so ElegantOTA can start from the asynchronous HTTP task while b_softSleep is true. OTA servicing is inside the awake-only loop section; without a main-loop wake, failure handling cannot clear b_ota and the scale can remain stuck in update mode.

The original wake guard also raced with pending remote sleep. BLE and WebSocket callbacks published b_softSleep = true before WSP_SLEEP_ON actually powered the rails down. OTA could clear that requested state, after which the still-pending command powered the rails down without restoring b_softSleep, leaving the software state and hardware state inconsistent.

Implementation

  • processWsPendingCmds() now publishes soft-sleep state beside the actual rail shutdown.
  • BLE and WebSocket callbacks only replace the pending sleep command.
  • A wake request atomically replaces pending sleep/display-off intent and is interpreted against applied state in the main loop.
  • processWsPendingCmds() runs before the OTA wake guard, so a pending sleep is applied and immediately recovered in the same loop pass when OTA is active.

Safety / Reliability Impact

Async callbacks still perform no OLED, SPI, I2C, rail, or ADC work. The main loop remains the sole owner of remote sleep hardware transitions, and OTA servicing always reaches a powered, internally consistent state.

Compatibility

No HTTP endpoint, manifest, BLE, USB, WebSocket, storage, or reboot wire contract changes. Starting ElegantOTA while soft asleep now wakes the scale and display. Native, grinder, custom, and hardware targets were intentionally not run.

Regression Coverage

  • tools/test_ota_reboot_routing_contract.py exercises pending-sleep plus asynchronous OTA start and requires pending-command dispatch before OTA recovery.
  • tools/test_soft_sleep_ads_wake.py requires callbacks to defer state publication, latest wake intent to replace pending sleep, and applied state to change beside rail shutdown.

Verification

  • python tools/test_ota_reboot_routing_contract.py
  • python tools/test_soft_sleep_ads_wake.py
  • python tools/test_pull_ota_contract.py
  • python tools/test_ota_input_isolation_contract.py
  • python tools/test_charging_wake_contract.py
  • python tools/test_ble_subscription_contract.py
  • pio run -e esp32s3 with an isolated PLATFORMIO_CORE_DIR
  • git diff --check

All passed. The ESP32-S3 build retains only the existing volatile-increment warnings in src/wifi_setup.cpp.

Hardware Verification

Not run. No physical soft-sleep HTTP upload, induced failure, recovery, or reboot was exercised.

@ODevStudio
ODevStudio marked this pull request as ready for review August 13, 2026 11:09
@ODevStudio
ODevStudio force-pushed the audit/pr-018-wake-elegant-ota branch from 7c29c35 to f944fdb Compare August 13, 2026 11:15
@ODevStudio
ODevStudio merged commit 0eef468 into main Aug 13, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant