Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>
Co-authored-by: J. Nick Koston <nick@koston.org>
For OTA_TYPE_UPDATE_PARTITION_TABLE the success path runs
nvs_flash_deinit() before the final write, which leaves every
preference handle held by other components invalid. App.safe_reboot()
calls on_safe_shutdown() which tries to flush preferences, and each
flush fails with ESP_ERR_NVS_INVALID_HANDLE -- noisy log spam during
the reboot window.
App.reboot() skips the safe-shutdown callbacks and goes straight to
esp_restart(). For partition-table OTAs there is nothing useful to
flush (NVS handles are already dead, the device is moments from a
reboot anyway), so reboot directly.
App-OTA path is unchanged: safe_reboot() still runs on_safe_shutdown
so preferences are saved on the way out.
When the running app does not fit any slot in the new partition table,
the user has almost certainly picked the wrong migration .bin for
their device. Replace the generic "No compatible app partition found"
error with one that prints the running app's offset, used size, and
the size limit a migration method must clear, plus an explicit
reassurance that no flash content has been modified yet.
Same treatment for the otadata-overlap case: include the running app
offset/size and tell the user to pick a different migration method.
Verification phase is non-destructive, so these errors are recoverable
by retrying with the correct .bin -- the new wording makes that
explicit so users don't lose time on a brick scare they aren't in.
No code-flow change; only log message wording.
The fixture shares the `host-climate-test` build dir with
host_mode_climate_control.yaml. When the control test runs first and
leaves the thermostat in HEAT mode, MEMORY restore on the next basic_state
boot picked up HEAT and the initial-state assertion failed
(`assert ClimateMode.HEAT == ClimateMode.OFF`).
`const Ts &...` is ill-formed when Ts is already a reference (e.g. a
trigger that passes `std::string &`). Forward Ts by-value so the
generated lambda matches ApplyFn for any valid trigger arg type.
`const Ts &...` is ill-formed when Ts is already a reference (e.g. a
trigger that passes `std::string &`). Forward Ts by-value so the
generated lambda matches ApplyFn for any valid trigger arg type.
`const Ts &...` is ill-formed when Ts is already a reference (e.g. a
trigger that passes `std::string &`). Forward Ts by-value so the
generated lambda matches ApplyFn for any valid trigger arg type.
`const Ts &...` is ill-formed when Ts is already a reference (e.g. a
trigger that passes `std::string &`). Forward Ts by-value so the
generated lambda matches ApplyFn for any valid trigger arg type.
Mat931 verified empirically that ``nvs_flash_init()`` after
``nvs_flash_deinit()`` does not revive NVS handles already held by
other components: writes still fail with ESP_ERR_NVS_INVALID_HANDLE.
The guard therefore only created the appearance of a recovery path.
Remove it and document the actual contract: from nvs_flash_deinit()
onward, components that hold open NVS handles will fail until the
device is rebooted. The success path reboots immediately, so it is
unaffected; the failure path now tells the user clearly to reboot
and retry, rather than implying retry-without-reboot will work.
Also soften the "permanently brick" wording in the pre-write log
warning -- a bad partition-table OTA leaves a device that needs a
serial flash to recover, not a permanently-dead one.