diff --git a/esphome/components/ota/ota_backend.cpp b/esphome/components/ota/ota_backend.cpp index 8fb9f67214..01a18a58ef 100644 --- a/esphome/components/ota/ota_backend.cpp +++ b/esphome/components/ota/ota_backend.cpp @@ -13,6 +13,19 @@ OTAGlobalCallback *get_global_ota_callback() { return global_ota_callback; } +void OTAComponent::notify_state_deferred_(OTAState state, float progress, uint8_t error) { + // Pack state, error, and progress into a single uint32_t so the lambda + // captures only [this, packed] (8 bytes) — fits in std::function SBO. + // Layout: [state:8][error:8][progress_fixed:16] where progress is 0–10000 (0.01% resolution) + static_assert(OTA_ERROR <= 0xFF, "OTAState must fit in 8 bits for packing"); + uint32_t packed = (static_cast(state) << 24) | (static_cast(error) << 16) | + static_cast(progress * 100.0f); + this->defer([this, packed]() { + this->notify_state_(static_cast(packed >> 24), static_cast(packed & 0xFFFF) / 100.0f, + static_cast(packed >> 16)); + }); +} + void OTAComponent::notify_state_(OTAState state, float progress, uint8_t error) { for (auto *listener : this->state_listeners_) { listener->on_ota_state(state, progress, error); diff --git a/esphome/components/ota/ota_backend.h b/esphome/components/ota/ota_backend.h index 8a71135477..ab0ec58e8a 100644 --- a/esphome/components/ota/ota_backend.h +++ b/esphome/components/ota/ota_backend.h @@ -73,18 +73,7 @@ class OTAComponent : public Component { * This should be used by OTA implementations that run in separate tasks * (like web_server OTA) to ensure listeners execute in the main loop. */ - void notify_state_deferred_(OTAState state, float progress, uint8_t error) { - // Pack state, error, and progress into a single uint32_t so the lambda - // captures only [this, packed] (8 bytes) — intended to fit in std::function SBO on supported toolchains. - // Layout: [state:8][error:8][progress_fixed:16] where progress is 0–10000 (0.01% resolution) - static_assert(OTA_ERROR <= 0xFF, "OTAState must fit in 8 bits for packing"); - uint32_t packed = (static_cast(state) << 24) | (static_cast(error) << 16) | - static_cast(progress * 100.0f); - this->defer([this, packed]() { - this->notify_state_(static_cast(packed >> 24), static_cast(packed & 0xFFFF) / 100.0f, - static_cast(packed >> 16)); - }); - } + void notify_state_deferred_(OTAState state, float progress, uint8_t error); std::vector state_listeners_; #endif