1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-06 05:12:21 +01:00

move ota to ota_network

This commit is contained in:
Tomasz Duda
2024-02-12 01:40:10 +01:00
parent def796cd3a
commit f00476c9cc
18 changed files with 122 additions and 61 deletions

View File

@@ -33,7 +33,14 @@ CONF_ON_ERROR = "on_error"
ota_ns = cg.esphome_ns.namespace("ota") ota_ns = cg.esphome_ns.namespace("ota")
OTAState = ota_ns.enum("OTAState") OTAState = ota_ns.enum("OTAState")
OTAComponent = ota_ns.class_("OTAComponent", cg.Component) if CORE.using_zephyr:
OTAComponent = cg.esphome_ns.namespace("ota_mcuboot").class_(
"OTAComponent", cg.Component
)
else:
OTAComponent = cg.esphome_ns.namespace("ota_network").class_(
"OTAComponent", cg.Component
)
OTAStateChangeTrigger = ota_ns.class_( OTAStateChangeTrigger = ota_ns.class_(
"OTAStateChangeTrigger", automation.Trigger.template() "OTAStateChangeTrigger", automation.Trigger.template()
) )
@@ -43,11 +50,25 @@ OTAEndTrigger = ota_ns.class_("OTAEndTrigger", automation.Trigger.template())
OTAErrorTrigger = ota_ns.class_("OTAErrorTrigger", automation.Trigger.template()) OTAErrorTrigger = ota_ns.class_("OTAErrorTrigger", automation.Trigger.template())
def not_supported_by_zephyr(value):
if CORE.using_zephyr:
raise cv.Invalid(f"Not supported by zephyr framework({value})")
return value
def _default_ota_version():
if CORE.using_zephyr:
return cv.UNDEFINED
return 2
CONFIG_SCHEMA = cv.Schema( CONFIG_SCHEMA = cv.Schema(
{ {
cv.GenerateID(): cv.declare_id(OTAComponent), cv.GenerateID(): cv.declare_id(OTAComponent),
cv.Optional(CONF_SAFE_MODE, default=True): cv.boolean, cv.Optional(CONF_SAFE_MODE, default=True): cv.boolean,
cv.Optional(CONF_VERSION, default=2): cv.one_of(1, 2, int=True), cv.Optional(CONF_VERSION, default=_default_ota_version()): cv.All(
cv.one_of(1, 2, int=True), not_supported_by_zephyr
),
cv.SplitDefault( cv.SplitDefault(
CONF_PORT, CONF_PORT,
esp8266=8266, esp8266=8266,
@@ -55,8 +76,11 @@ CONFIG_SCHEMA = cv.Schema(
rp2040=2040, rp2040=2040,
bk72xx=8892, bk72xx=8892,
rtl87xx=8892, rtl87xx=8892,
): cv.port, ): cv.All(
cv.Optional(CONF_PASSWORD): cv.string, cv.port,
not_supported_by_zephyr,
),
cv.Optional(CONF_PASSWORD): cv.All(cv.string, not_supported_by_zephyr),
cv.Optional( cv.Optional(
CONF_REBOOT_TIMEOUT, default="5min" CONF_REBOOT_TIMEOUT, default="5min"
): cv.positive_time_period_milliseconds, ): cv.positive_time_period_milliseconds,
@@ -95,8 +119,9 @@ async def to_code(config):
CORE.data[CONF_OTA] = {} CORE.data[CONF_OTA] = {}
var = cg.new_Pvariable(config[CONF_ID]) var = cg.new_Pvariable(config[CONF_ID])
# cg.add(var.set_port(config[CONF_PORT]))
cg.add_define("USE_OTA") cg.add_define("USE_OTA")
if not CORE.using_zephyr:
cg.add(var.set_port(config[CONF_PORT]))
if CONF_PASSWORD in config: if CONF_PASSWORD in config:
cg.add(var.set_auth_password(config[CONF_PASSWORD])) cg.add(var.set_auth_password(config[CONF_PASSWORD]))
cg.add_define("USE_OTA_PASSWORD") cg.add_define("USE_OTA_PASSWORD")

View File

@@ -0,0 +1,15 @@
#include "ota_component.h"
namespace esphome {
namespace ota {
OTAComponent *global_ota_component = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
#ifdef USE_OTA_STATE_CALLBACK
void OTAComponent::add_on_state_callback(std::function<void(OTAState, float, uint8_t)> &&callback) {
this->state_callback_.add(std::move(callback));
}
#endif
} // namespace ota
} // namespace esphome

View File

@@ -0,0 +1,31 @@
#pragma once
#include "esphome/core/defines.h"
#include "esphome/core/component.h"
#include "esphome/core/helpers.h"
namespace esphome {
namespace ota {
enum OTAState { OTA_COMPLETED = 0, OTA_STARTED, OTA_IN_PROGRESS, OTA_ERROR };
class OTAComponent : public Component {
public:
virtual bool should_enter_safe_mode(uint8_t num_attempts, uint32_t enable_time){ return false;}
/// Set to true if the next startup will enter safe mode
virtual void set_safe_mode_pending(const bool &pending){}
virtual bool get_safe_mode_pending() {return false;}
#ifdef USE_OTA_STATE_CALLBACK
void add_on_state_callback(std::function<void(OTAState, float, uint8_t)> &&callback);
#endif
protected:
#ifdef USE_OTA_STATE_CALLBACK
CallbackManager<void(OTAState, float, uint8_t)> state_callback_{};
#endif
};
extern OTAComponent *global_ota_component; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
} // namespace ota
} // namespace esphome

View File

@@ -0,0 +1,12 @@
#pragma once
#include "esphome/components/ota/ota_component.h"
namespace esphome {
namespace ota_mcuboot {
class OTAComponent : public ota::OTAComponent {
};
}
}

View File

@@ -2,7 +2,7 @@
#include "ota_component.h" #include "ota_component.h"
namespace esphome { namespace esphome {
namespace ota { namespace ota_network {
class OTABackend { class OTABackend {
public: public:

View File

@@ -8,7 +8,7 @@
#include <Update.h> #include <Update.h>
namespace esphome { namespace esphome {
namespace ota { namespace ota_network {
OTAResponseTypes ArduinoESP32OTABackend::begin(size_t image_size) { OTAResponseTypes ArduinoESP32OTABackend::begin(size_t image_size) {
bool ret = Update.begin(image_size, U_FLASH); bool ret = Update.begin(image_size, U_FLASH);

View File

@@ -6,7 +6,7 @@
#include "ota_backend.h" #include "ota_backend.h"
namespace esphome { namespace esphome {
namespace ota { namespace ota_network {
class ArduinoESP32OTABackend : public OTABackend { class ArduinoESP32OTABackend : public OTABackend {
public: public:

View File

@@ -10,7 +10,7 @@
#include <Updater.h> #include <Updater.h>
namespace esphome { namespace esphome {
namespace ota { namespace ota_network {
OTAResponseTypes ArduinoESP8266OTABackend::begin(size_t image_size) { OTAResponseTypes ArduinoESP8266OTABackend::begin(size_t image_size) {
bool ret = Update.begin(image_size, U_FLASH); bool ret = Update.begin(image_size, U_FLASH);

View File

@@ -8,7 +8,7 @@
#include "esphome/core/macros.h" #include "esphome/core/macros.h"
namespace esphome { namespace esphome {
namespace ota { namespace ota_network {
class ArduinoESP8266OTABackend : public OTABackend { class ArduinoESP8266OTABackend : public OTABackend {
public: public:

View File

@@ -8,7 +8,7 @@
#include <Update.h> #include <Update.h>
namespace esphome { namespace esphome {
namespace ota { namespace ota_network {
OTAResponseTypes ArduinoLibreTinyOTABackend::begin(size_t image_size) { OTAResponseTypes ArduinoLibreTinyOTABackend::begin(size_t image_size) {
bool ret = Update.begin(image_size, U_FLASH); bool ret = Update.begin(image_size, U_FLASH);

View File

@@ -6,7 +6,7 @@
#include "ota_backend.h" #include "ota_backend.h"
namespace esphome { namespace esphome {
namespace ota { namespace ota_network {
class ArduinoLibreTinyOTABackend : public OTABackend { class ArduinoLibreTinyOTABackend : public OTABackend {
public: public:

View File

@@ -10,7 +10,7 @@
#include <Updater.h> #include <Updater.h>
namespace esphome { namespace esphome {
namespace ota { namespace ota_network {
OTAResponseTypes ArduinoRP2040OTABackend::begin(size_t image_size) { OTAResponseTypes ArduinoRP2040OTABackend::begin(size_t image_size) {
bool ret = Update.begin(image_size, U_FLASH); bool ret = Update.begin(image_size, U_FLASH);

View File

@@ -8,7 +8,7 @@
#include "ota_component.h" #include "ota_component.h"
namespace esphome { namespace esphome {
namespace ota { namespace ota_network {
class ArduinoRP2040OTABackend : public OTABackend { class ArduinoRP2040OTABackend : public OTABackend {
public: public:

View File

@@ -13,7 +13,7 @@
#endif #endif
namespace esphome { namespace esphome {
namespace ota { namespace ota_network {
OTAResponseTypes IDFOTABackend::begin(size_t image_size) { OTAResponseTypes IDFOTABackend::begin(size_t image_size) {
this->partition_ = esp_ota_get_next_update_partition(nullptr); this->partition_ = esp_ota_get_next_update_partition(nullptr);

View File

@@ -8,7 +8,7 @@
#include "esphome/components/md5/md5.h" #include "esphome/components/md5/md5.h"
namespace esphome { namespace esphome {
namespace ota { namespace ota_network {
class IDFOTABackend : public OTABackend { class IDFOTABackend : public OTABackend {
public: public:

View File

@@ -17,13 +17,11 @@
#include <cstdio> #include <cstdio>
namespace esphome { namespace esphome {
namespace ota { namespace ota_network {
static const char *const TAG = "ota"; static const char *const TAG = "ota";
static constexpr u_int16_t OTA_BLOCK_SIZE = 8192; static constexpr u_int16_t OTA_BLOCK_SIZE = 8192;
OTAComponent *global_ota_component = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
std::unique_ptr<OTABackend> make_ota_backend() { std::unique_ptr<OTABackend> make_ota_backend() {
#ifdef USE_ARDUINO #ifdef USE_ARDUINO
#ifdef USE_ESP8266 #ifdef USE_ESP8266
@@ -44,7 +42,7 @@ std::unique_ptr<OTABackend> make_ota_backend() {
#endif #endif
} }
OTAComponent::OTAComponent() { global_ota_component = this; } OTAComponent::OTAComponent() { ota::global_ota_component = this; }
void OTAComponent::setup() { void OTAComponent::setup() {
server_ = socket::socket_ip(SOCK_STREAM, 0); server_ = socket::socket_ip(SOCK_STREAM, 0);
@@ -102,7 +100,7 @@ void OTAComponent::dump_config() {
#endif #endif
ESP_LOGCONFIG(TAG, " OTA version: %d.", USE_OTA_VERSION); ESP_LOGCONFIG(TAG, " OTA version: %d.", USE_OTA_VERSION);
if (this->has_safe_mode_ && this->safe_mode_rtc_value_ > 1 && if (this->has_safe_mode_ && this->safe_mode_rtc_value_ > 1 &&
this->safe_mode_rtc_value_ != esphome::ota::OTAComponent::ENTER_SAFE_MODE_MAGIC) { this->safe_mode_rtc_value_ != esphome::ota_network::OTAComponent::ENTER_SAFE_MODE_MAGIC) {
ESP_LOGW(TAG, "Last Boot was an unhandled reset, will proceed to safe mode in %" PRIu32 " restarts", ESP_LOGW(TAG, "Last Boot was an unhandled reset, will proceed to safe mode in %" PRIu32 " restarts",
this->safe_mode_num_attempts_ - this->safe_mode_rtc_value_); this->safe_mode_num_attempts_ - this->safe_mode_rtc_value_);
} }
@@ -154,7 +152,7 @@ void OTAComponent::handle_() {
ESP_LOGD(TAG, "Starting OTA Update from %s...", this->client_->getpeername().c_str()); ESP_LOGD(TAG, "Starting OTA Update from %s...", this->client_->getpeername().c_str());
this->status_set_warning(); this->status_set_warning();
#ifdef USE_OTA_STATE_CALLBACK #ifdef USE_OTA_STATE_CALLBACK
this->state_callback_.call(OTA_STARTED, 0.0f, 0); this->state_callback_.call(ota::OTA_STARTED, 0.0f, 0);
#endif #endif
if (!this->readall_(buf, 5)) { if (!this->readall_(buf, 5)) {
@@ -329,7 +327,7 @@ void OTAComponent::handle_() {
float percentage = (total * 100.0f) / ota_size; float percentage = (total * 100.0f) / ota_size;
ESP_LOGD(TAG, "OTA in progress: %0.1f%%", percentage); ESP_LOGD(TAG, "OTA in progress: %0.1f%%", percentage);
#ifdef USE_OTA_STATE_CALLBACK #ifdef USE_OTA_STATE_CALLBACK
this->state_callback_.call(OTA_IN_PROGRESS, percentage, 0); this->state_callback_.call(ota::OTA_IN_PROGRESS, percentage, 0);
#endif #endif
// feed watchdog and give other tasks a chance to run // feed watchdog and give other tasks a chance to run
App.feed_wdt(); App.feed_wdt();
@@ -363,7 +361,7 @@ void OTAComponent::handle_() {
ESP_LOGI(TAG, "OTA update finished!"); ESP_LOGI(TAG, "OTA update finished!");
this->status_clear_warning(); this->status_clear_warning();
#ifdef USE_OTA_STATE_CALLBACK #ifdef USE_OTA_STATE_CALLBACK
this->state_callback_.call(OTA_COMPLETED, 100.0f, 0); this->state_callback_.call(ota::OTA_COMPLETED, 100.0f, 0);
#endif #endif
delay(100); // NOLINT delay(100); // NOLINT
App.safe_reboot(); App.safe_reboot();
@@ -380,7 +378,7 @@ error:
this->status_momentary_error("onerror", 5000); this->status_momentary_error("onerror", 5000);
#ifdef USE_OTA_STATE_CALLBACK #ifdef USE_OTA_STATE_CALLBACK
this->state_callback_.call(OTA_ERROR, 0.0f, static_cast<uint8_t>(error_code)); this->state_callback_.call(ota::OTA_ERROR, 0.0f, static_cast<uint8_t>(error_code));
#endif #endif
} }
@@ -453,18 +451,18 @@ void OTAComponent::set_safe_mode_pending(const bool &pending) {
uint32_t current_rtc = this->read_rtc_(); uint32_t current_rtc = this->read_rtc_();
if (pending && current_rtc != esphome::ota::OTAComponent::ENTER_SAFE_MODE_MAGIC) { if (pending && current_rtc != esphome::ota_network::OTAComponent::ENTER_SAFE_MODE_MAGIC) {
ESP_LOGI(TAG, "Device will enter safe mode on next boot."); ESP_LOGI(TAG, "Device will enter safe mode on next boot.");
this->write_rtc_(esphome::ota::OTAComponent::ENTER_SAFE_MODE_MAGIC); this->write_rtc_(esphome::ota_network::OTAComponent::ENTER_SAFE_MODE_MAGIC);
} }
if (!pending && current_rtc == esphome::ota::OTAComponent::ENTER_SAFE_MODE_MAGIC) { if (!pending && current_rtc == esphome::ota_network::OTAComponent::ENTER_SAFE_MODE_MAGIC) {
ESP_LOGI(TAG, "Safe mode pending has been cleared"); ESP_LOGI(TAG, "Safe mode pending has been cleared");
this->clean_rtc(); this->clean_rtc();
} }
} }
bool OTAComponent::get_safe_mode_pending() { bool OTAComponent::get_safe_mode_pending() {
return this->has_safe_mode_ && this->read_rtc_() == esphome::ota::OTAComponent::ENTER_SAFE_MODE_MAGIC; return this->has_safe_mode_ && this->read_rtc_() == esphome::ota_network::OTAComponent::ENTER_SAFE_MODE_MAGIC;
} }
bool OTAComponent::should_enter_safe_mode(uint8_t num_attempts, uint32_t enable_time) { bool OTAComponent::should_enter_safe_mode(uint8_t num_attempts, uint32_t enable_time) {
@@ -475,7 +473,7 @@ bool OTAComponent::should_enter_safe_mode(uint8_t num_attempts, uint32_t enable_
this->rtc_ = global_preferences->make_preference<uint32_t>(233825507UL, false); this->rtc_ = global_preferences->make_preference<uint32_t>(233825507UL, false);
this->safe_mode_rtc_value_ = this->read_rtc_(); this->safe_mode_rtc_value_ = this->read_rtc_();
bool is_manual_safe_mode = this->safe_mode_rtc_value_ == esphome::ota::OTAComponent::ENTER_SAFE_MODE_MAGIC; bool is_manual_safe_mode = this->safe_mode_rtc_value_ == esphome::ota_network::OTAComponent::ENTER_SAFE_MODE_MAGIC;
if (is_manual_safe_mode) { if (is_manual_safe_mode) {
ESP_LOGI(TAG, "Safe mode has been entered manually"); ESP_LOGI(TAG, "Safe mode has been entered manually");
@@ -521,15 +519,9 @@ uint32_t OTAComponent::read_rtc_() {
} }
void OTAComponent::clean_rtc() { this->write_rtc_(0); } void OTAComponent::clean_rtc() { this->write_rtc_(0); }
void OTAComponent::on_safe_shutdown() { void OTAComponent::on_safe_shutdown() {
if (this->has_safe_mode_ && this->read_rtc_() != esphome::ota::OTAComponent::ENTER_SAFE_MODE_MAGIC) if (this->has_safe_mode_ && this->read_rtc_() != esphome::ota_network::OTAComponent::ENTER_SAFE_MODE_MAGIC)
this->clean_rtc(); this->clean_rtc();
} }
#ifdef USE_OTA_STATE_CALLBACK
void OTAComponent::add_on_state_callback(std::function<void(OTAState, float, uint8_t)> &&callback) {
this->state_callback_.add(std::move(callback));
}
#endif
} // namespace ota } // namespace ota
} // namespace esphome } // namespace esphome

View File

@@ -1,13 +1,11 @@
#pragma once #pragma once
#include "esphome/components/socket/socket.h" #include "esphome/components/socket/socket.h"
#include "esphome/core/component.h"
#include "esphome/core/preferences.h" #include "esphome/core/preferences.h"
#include "esphome/core/helpers.h" #include "esphome/components/ota/ota_component.h"
#include "esphome/core/defines.h"
namespace esphome { namespace esphome {
namespace ota { namespace ota_network {
enum OTAResponseTypes { enum OTAResponseTypes {
OTA_RESPONSE_OK = 0x00, OTA_RESPONSE_OK = 0x00,
@@ -38,10 +36,8 @@ enum OTAResponseTypes {
OTA_RESPONSE_ERROR_UNKNOWN = 0xFF, OTA_RESPONSE_ERROR_UNKNOWN = 0xFF,
}; };
enum OTAState { OTA_COMPLETED = 0, OTA_STARTED, OTA_IN_PROGRESS, OTA_ERROR };
/// OTAComponent provides a simple way to integrate Over-the-Air updates into your app using ArduinoOTA. /// OTAComponent provides a simple way to integrate Over-the-Air updates into your app using ArduinoOTA.
class OTAComponent : public Component { class OTAComponent : public ota::OTAComponent {
public: public:
OTAComponent(); OTAComponent();
#ifdef USE_OTA_PASSWORD #ifdef USE_OTA_PASSWORD
@@ -51,15 +47,11 @@ class OTAComponent : public Component {
/// Manually set the port OTA should listen on. /// Manually set the port OTA should listen on.
void set_port(uint16_t port); void set_port(uint16_t port);
bool should_enter_safe_mode(uint8_t num_attempts, uint32_t enable_time); bool should_enter_safe_mode(uint8_t num_attempts, uint32_t enable_time) override;
/// Set to true if the next startup will enter safe mode /// Set to true if the next startup will enter safe mode
void set_safe_mode_pending(const bool &pending); void set_safe_mode_pending(const bool &pending) override;
bool get_safe_mode_pending(); bool get_safe_mode_pending() override;
#ifdef USE_OTA_STATE_CALLBACK
void add_on_state_callback(std::function<void(OTAState, float, uint8_t)> &&callback);
#endif
// ========== INTERNAL METHODS ========== // ========== INTERNAL METHODS ==========
// (In most use cases you won't need these) // (In most use cases you won't need these)
@@ -100,13 +92,7 @@ class OTAComponent : public Component {
static const uint32_t ENTER_SAFE_MODE_MAGIC = static const uint32_t ENTER_SAFE_MODE_MAGIC =
0x5afe5afe; ///< a magic number to indicate that safe mode should be entered on next boot 0x5afe5afe; ///< a magic number to indicate that safe mode should be entered on next boot
#ifdef USE_OTA_STATE_CALLBACK
CallbackManager<void(OTAState, float, uint8_t)> state_callback_{};
#endif
}; };
extern OTAComponent *global_ota_component; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
} // namespace ota } // namespace ota
} // namespace esphome } // namespace esphome