1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-04 04:12:23 +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")
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", automation.Trigger.template()
)
@@ -43,11 +50,25 @@ OTAEndTrigger = ota_ns.class_("OTAEndTrigger", 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(
{
cv.GenerateID(): cv.declare_id(OTAComponent),
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(
CONF_PORT,
esp8266=8266,
@@ -55,8 +76,11 @@ CONFIG_SCHEMA = cv.Schema(
rp2040=2040,
bk72xx=8892,
rtl87xx=8892,
): cv.port,
cv.Optional(CONF_PASSWORD): cv.string,
): cv.All(
cv.port,
not_supported_by_zephyr,
),
cv.Optional(CONF_PASSWORD): cv.All(cv.string, not_supported_by_zephyr),
cv.Optional(
CONF_REBOOT_TIMEOUT, default="5min"
): cv.positive_time_period_milliseconds,
@@ -95,12 +119,13 @@ async def to_code(config):
CORE.data[CONF_OTA] = {}
var = cg.new_Pvariable(config[CONF_ID])
# cg.add(var.set_port(config[CONF_PORT]))
cg.add_define("USE_OTA")
if CONF_PASSWORD in config:
cg.add(var.set_auth_password(config[CONF_PASSWORD]))
cg.add_define("USE_OTA_PASSWORD")
cg.add_define("USE_OTA_VERSION", config[CONF_VERSION])
if not CORE.using_zephyr:
cg.add(var.set_port(config[CONF_PORT]))
if CONF_PASSWORD in config:
cg.add(var.set_auth_password(config[CONF_PASSWORD]))
cg.add_define("USE_OTA_PASSWORD")
cg.add_define("USE_OTA_VERSION", config[CONF_VERSION])
await cg.register_component(var, config)

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"
namespace esphome {
namespace ota {
namespace ota_network {
class OTABackend {
public:

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -17,13 +17,11 @@
#include <cstdio>
namespace esphome {
namespace ota {
namespace ota_network {
static const char *const TAG = "ota";
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() {
#ifdef USE_ARDUINO
#ifdef USE_ESP8266
@@ -44,7 +42,7 @@ std::unique_ptr<OTABackend> make_ota_backend() {
#endif
}
OTAComponent::OTAComponent() { global_ota_component = this; }
OTAComponent::OTAComponent() { ota::global_ota_component = this; }
void OTAComponent::setup() {
server_ = socket::socket_ip(SOCK_STREAM, 0);
@@ -102,7 +100,7 @@ void OTAComponent::dump_config() {
#endif
ESP_LOGCONFIG(TAG, " OTA version: %d.", USE_OTA_VERSION);
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",
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());
this->status_set_warning();
#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
if (!this->readall_(buf, 5)) {
@@ -329,7 +327,7 @@ void OTAComponent::handle_() {
float percentage = (total * 100.0f) / ota_size;
ESP_LOGD(TAG, "OTA in progress: %0.1f%%", percentage);
#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
// feed watchdog and give other tasks a chance to run
App.feed_wdt();
@@ -363,7 +361,7 @@ void OTAComponent::handle_() {
ESP_LOGI(TAG, "OTA update finished!");
this->status_clear_warning();
#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
delay(100); // NOLINT
App.safe_reboot();
@@ -380,7 +378,7 @@ error:
this->status_momentary_error("onerror", 5000);
#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
}
@@ -453,18 +451,18 @@ void OTAComponent::set_safe_mode_pending(const bool &pending) {
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.");
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");
this->clean_rtc();
}
}
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) {
@@ -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->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) {
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::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();
}
#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

@@ -1,13 +1,11 @@
#pragma once
#include "esphome/components/socket/socket.h"
#include "esphome/core/component.h"
#include "esphome/core/preferences.h"
#include "esphome/core/helpers.h"
#include "esphome/core/defines.h"
#include "esphome/components/ota/ota_component.h"
namespace esphome {
namespace ota {
namespace ota_network {
enum OTAResponseTypes {
OTA_RESPONSE_OK = 0x00,
@@ -38,10 +36,8 @@ enum OTAResponseTypes {
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.
class OTAComponent : public Component {
class OTAComponent : public ota::OTAComponent {
public:
OTAComponent();
#ifdef USE_OTA_PASSWORD
@@ -51,15 +47,11 @@ class OTAComponent : public Component {
/// Manually set the port OTA should listen on.
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
void set_safe_mode_pending(const bool &pending);
bool get_safe_mode_pending();
#ifdef USE_OTA_STATE_CALLBACK
void add_on_state_callback(std::function<void(OTAState, float, uint8_t)> &&callback);
#endif
void set_safe_mode_pending(const bool &pending) override;
bool get_safe_mode_pending() override;
// ========== INTERNAL METHODS ==========
// (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 =
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 esphome