mirror of
https://github.com/esphome/esphome.git
synced 2025-02-13 06:51:02 +01:00
Multi source ota update
This commit is contained in:
parent
e04743e381
commit
0475dd8af4
3 changed files with 31 additions and 19 deletions
esphome/components/http_request/update
|
@ -1,15 +1,11 @@
|
|||
import esphome.config_validation as cv
|
||||
import esphome.codegen as cg
|
||||
|
||||
from esphome.components import update
|
||||
from esphome.const import (
|
||||
CONF_SOURCE,
|
||||
)
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_SOURCE
|
||||
|
||||
from .. import http_request_ns, CONF_HTTP_REQUEST_ID, HttpRequestComponent
|
||||
from .. import CONF_HTTP_REQUEST_ID, HttpRequestComponent, http_request_ns
|
||||
from ..ota import OtaHttpRequestComponent
|
||||
|
||||
|
||||
AUTO_LOAD = ["json"]
|
||||
CODEOWNERS = ["@jesserockz"]
|
||||
DEPENDENCIES = ["ota.http_request"]
|
||||
|
@ -25,7 +21,7 @@ CONFIG_SCHEMA = update.UPDATE_SCHEMA.extend(
|
|||
cv.GenerateID(): cv.declare_id(HttpRequestUpdate),
|
||||
cv.GenerateID(CONF_OTA_ID): cv.use_id(OtaHttpRequestComponent),
|
||||
cv.GenerateID(CONF_HTTP_REQUEST_ID): cv.use_id(HttpRequestComponent),
|
||||
cv.Required(CONF_SOURCE): cv.url,
|
||||
cv.Required(CONF_SOURCE): cv.ensure_list(cv.url),
|
||||
}
|
||||
).extend(cv.polling_component_schema("6h"))
|
||||
|
||||
|
@ -37,7 +33,7 @@ async def to_code(config):
|
|||
request_parent = await cg.get_variable(config[CONF_HTTP_REQUEST_ID])
|
||||
cg.add(var.set_request_parent(request_parent))
|
||||
|
||||
cg.add(var.set_source_url(config[CONF_SOURCE]))
|
||||
cg.add(var.set_source_urls(config[CONF_SOURCE]))
|
||||
|
||||
cg.add_define("USE_OTA_STATE_CALLBACK")
|
||||
|
||||
|
|
|
@ -21,19 +21,33 @@ void HttpRequestUpdate::setup() {
|
|||
this->update_info_.progress = progress;
|
||||
this->publish_state();
|
||||
} else if (state == ota::OTAState::OTA_ABORT || state == ota::OTAState::OTA_ERROR) {
|
||||
this->state_ = update::UPDATE_STATE_AVAILABLE;
|
||||
this->status_set_error("Failed to install firmware");
|
||||
this->publish_state();
|
||||
if (this->current_source_ + 1 < this->source_urls_.size()) {
|
||||
this->current_source_++;
|
||||
this->defer("update", [this]() {
|
||||
this->update();
|
||||
this->perform(true);
|
||||
});
|
||||
} else {
|
||||
this->current_source_ = 0;
|
||||
this->state_ = update::UPDATE_STATE_AVAILABLE;
|
||||
this->status_set_error("Failed to install firmware");
|
||||
this->publish_state();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void HttpRequestUpdate::update() {
|
||||
auto container = this->request_parent_->get(this->source_url_);
|
||||
std::string current_source = this->source_urls_[this->current_source_];
|
||||
auto container = this->request_parent_->get(current_source);
|
||||
|
||||
if (container == nullptr || container->status_code != HTTP_STATUS_OK) {
|
||||
std::string msg = str_sprintf("Failed to fetch manifest from %s", this->source_url_.c_str());
|
||||
std::string msg = str_sprintf("Failed to fetch manifest from %s", current_source.c_str());
|
||||
this->status_set_error(msg.c_str());
|
||||
if (this->current_source_ + 1 < this->source_urls_.size()) {
|
||||
this->current_source_++;
|
||||
this->defer("update", [this]() { this->update(); });
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -99,7 +113,7 @@ void HttpRequestUpdate::update() {
|
|||
});
|
||||
|
||||
if (!valid) {
|
||||
std::string msg = str_sprintf("Failed to parse JSON from %s", this->source_url_.c_str());
|
||||
std::string msg = str_sprintf("Failed to parse JSON from %s", current_source.c_str());
|
||||
this->status_set_error(msg.c_str());
|
||||
return;
|
||||
}
|
||||
|
@ -108,10 +122,10 @@ void HttpRequestUpdate::update() {
|
|||
if (this->update_info_.firmware_url.find("http") == std::string::npos) {
|
||||
std::string path = this->update_info_.firmware_url;
|
||||
if (path[0] == '/') {
|
||||
std::string domain = this->source_url_.substr(0, this->source_url_.find('/', 8));
|
||||
std::string domain = current_source.substr(0, current_source.find('/', 8));
|
||||
this->update_info_.firmware_url = domain + path;
|
||||
} else {
|
||||
std::string domain = this->source_url_.substr(0, this->source_url_.rfind('/') + 1);
|
||||
std::string domain = current_source.substr(0, current_source.rfind('/') + 1);
|
||||
this->update_info_.firmware_url = domain + path;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,8 @@ class HttpRequestUpdate : public update::UpdateEntity, public PollingComponent {
|
|||
void perform(bool force) override;
|
||||
void check() override { this->update(); }
|
||||
|
||||
void set_source_url(const std::string &source_url) { this->source_url_ = source_url; }
|
||||
void set_source_url(const std::string &source_urls) { this->source_urls_ = {source_urls}; }
|
||||
void set_source_urls(const std::vector<std::string> &source_urls) { this->source_urls_ = source_urls; }
|
||||
|
||||
void set_request_parent(HttpRequestComponent *request_parent) { this->request_parent_ = request_parent; }
|
||||
void set_ota_parent(OtaHttpRequestComponent *ota_parent) { this->ota_parent_ = ota_parent; }
|
||||
|
@ -28,7 +29,8 @@ class HttpRequestUpdate : public update::UpdateEntity, public PollingComponent {
|
|||
protected:
|
||||
HttpRequestComponent *request_parent_;
|
||||
OtaHttpRequestComponent *ota_parent_;
|
||||
std::string source_url_;
|
||||
std::vector<std::string> source_urls_;
|
||||
size_t current_source_{0};
|
||||
};
|
||||
|
||||
} // namespace http_request
|
||||
|
|
Loading…
Add table
Reference in a new issue