mirror of
https://github.com/esphome/esphome.git
synced 2025-04-16 07:40:29 +01:00
Multi source ota update
This commit is contained in:
parent
e04743e381
commit
0475dd8af4
@ -1,15 +1,11 @@
|
|||||||
import esphome.config_validation as cv
|
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
|
|
||||||
from esphome.components import update
|
from esphome.components import update
|
||||||
from esphome.const import (
|
import esphome.config_validation as cv
|
||||||
CONF_SOURCE,
|
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
|
from ..ota import OtaHttpRequestComponent
|
||||||
|
|
||||||
|
|
||||||
AUTO_LOAD = ["json"]
|
AUTO_LOAD = ["json"]
|
||||||
CODEOWNERS = ["@jesserockz"]
|
CODEOWNERS = ["@jesserockz"]
|
||||||
DEPENDENCIES = ["ota.http_request"]
|
DEPENDENCIES = ["ota.http_request"]
|
||||||
@ -25,7 +21,7 @@ CONFIG_SCHEMA = update.UPDATE_SCHEMA.extend(
|
|||||||
cv.GenerateID(): cv.declare_id(HttpRequestUpdate),
|
cv.GenerateID(): cv.declare_id(HttpRequestUpdate),
|
||||||
cv.GenerateID(CONF_OTA_ID): cv.use_id(OtaHttpRequestComponent),
|
cv.GenerateID(CONF_OTA_ID): cv.use_id(OtaHttpRequestComponent),
|
||||||
cv.GenerateID(CONF_HTTP_REQUEST_ID): cv.use_id(HttpRequestComponent),
|
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"))
|
).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])
|
request_parent = await cg.get_variable(config[CONF_HTTP_REQUEST_ID])
|
||||||
cg.add(var.set_request_parent(request_parent))
|
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")
|
cg.add_define("USE_OTA_STATE_CALLBACK")
|
||||||
|
|
||||||
|
@ -21,19 +21,33 @@ void HttpRequestUpdate::setup() {
|
|||||||
this->update_info_.progress = progress;
|
this->update_info_.progress = progress;
|
||||||
this->publish_state();
|
this->publish_state();
|
||||||
} else if (state == ota::OTAState::OTA_ABORT || state == ota::OTAState::OTA_ERROR) {
|
} else if (state == ota::OTAState::OTA_ABORT || state == ota::OTAState::OTA_ERROR) {
|
||||||
this->state_ = update::UPDATE_STATE_AVAILABLE;
|
if (this->current_source_ + 1 < this->source_urls_.size()) {
|
||||||
this->status_set_error("Failed to install firmware");
|
this->current_source_++;
|
||||||
this->publish_state();
|
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() {
|
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) {
|
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());
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +113,7 @@ void HttpRequestUpdate::update() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!valid) {
|
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());
|
this->status_set_error(msg.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -108,10 +122,10 @@ void HttpRequestUpdate::update() {
|
|||||||
if (this->update_info_.firmware_url.find("http") == std::string::npos) {
|
if (this->update_info_.firmware_url.find("http") == std::string::npos) {
|
||||||
std::string path = this->update_info_.firmware_url;
|
std::string path = this->update_info_.firmware_url;
|
||||||
if (path[0] == '/') {
|
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;
|
this->update_info_.firmware_url = domain + path;
|
||||||
} else {
|
} 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;
|
this->update_info_.firmware_url = domain + path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,8 @@ class HttpRequestUpdate : public update::UpdateEntity, public PollingComponent {
|
|||||||
void perform(bool force) override;
|
void perform(bool force) override;
|
||||||
void check() override { this->update(); }
|
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_request_parent(HttpRequestComponent *request_parent) { this->request_parent_ = request_parent; }
|
||||||
void set_ota_parent(OtaHttpRequestComponent *ota_parent) { this->ota_parent_ = ota_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:
|
protected:
|
||||||
HttpRequestComponent *request_parent_;
|
HttpRequestComponent *request_parent_;
|
||||||
OtaHttpRequestComponent *ota_parent_;
|
OtaHttpRequestComponent *ota_parent_;
|
||||||
std::string source_url_;
|
std::vector<std::string> source_urls_;
|
||||||
|
size_t current_source_{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace http_request
|
} // namespace http_request
|
||||||
|
Loading…
x
Reference in New Issue
Block a user