This commit is contained in:
Michael Gorven 2024-05-02 14:27:54 +12:00 committed by GitHub
commit 4e0b63cbac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 41 additions and 5 deletions

View File

@ -4,6 +4,8 @@ import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import automation
from esphome.const import (
CONF_COUNT,
CONF_DELAY,
CONF_ID,
CONF_TIMEOUT,
CONF_METHOD,
@ -33,6 +35,8 @@ CONF_VERIFY_SSL = "verify_ssl"
CONF_ON_RESPONSE = "on_response"
CONF_FOLLOW_REDIRECTS = "follow_redirects"
CONF_REDIRECT_LIMIT = "redirect_limit"
CONF_RETRY = "retry"
CONF_BACKOFF_FACTOR = "backoff_factor"
def validate_url(value):
@ -78,6 +82,15 @@ CONFIG_SCHEMA = cv.All(
cv.Optional(
CONF_TIMEOUT, default="5s"
): cv.positive_time_period_milliseconds,
cv.Optional(CONF_RETRY, default={}): cv.Schema(
{
cv.Optional(CONF_COUNT, 0): cv.int_,
cv.Optional(
CONF_DELAY, default="1s"
): cv.positive_time_period_milliseconds,
cv.Optional(CONF_BACKOFF_FACTOR, 1.0): cv.float_,
}
),
cv.SplitDefault(CONF_ESP8266_DISABLE_SSL_SUPPORT, esp8266=False): cv.All(
cv.only_on_esp8266, cv.boolean
),
@ -96,6 +109,9 @@ async def to_code(config):
cg.add(var.set_useragent(config[CONF_USERAGENT]))
cg.add(var.set_follow_redirects(config[CONF_FOLLOW_REDIRECTS]))
cg.add(var.set_redirect_limit(config[CONF_REDIRECT_LIMIT]))
cg.add(var.set_retries(config[CONF_RETRY][CONF_COUNT]))
cg.add(var.set_retry_delay(config[CONF_RETRY][CONF_DELAY]))
cg.add(var.set_retry_backoff_factor(config[CONF_RETRY][CONF_BACKOFF_FACTOR]))
if CORE.is_esp8266 and not config[CONF_ESP8266_DISABLE_SSL_SUPPORT]:
cg.add_define("USE_HTTP_REQUEST_ESP8266_HTTPS")

View File

@ -31,11 +31,19 @@ void HttpRequestComponent::set_url(std::string url) {
}
void HttpRequestComponent::send(const std::vector<HttpRequestResponseTrigger *> &response_triggers) {
this->cancel_retry("http_request");
this->set_retry("http_request", this->retry_delay_, this->retries_ + 1,
std::bind(&HttpRequestComponent::send_, this, response_triggers, std::placeholders::_1),
this->retry_backoff_factor_);
}
RetryResult HttpRequestComponent::send_(const std::vector<HttpRequestResponseTrigger *> &response_triggers,
uint8_t attempt) {
if (!network::is_connected()) {
this->client_.end();
this->status_set_warning();
ESP_LOGW(TAG, "HTTP Request failed; Not connected to network");
return;
return RetryResult::RETRY;
}
bool begin_status = false;
@ -62,7 +70,7 @@ void HttpRequestComponent::send(const std::vector<HttpRequestResponseTrigger *>
this->client_.end();
this->status_set_warning();
ESP_LOGW(TAG, "HTTP Request failed at the begin phase. Please check the configuration");
return;
return RetryResult::DONE;
}
this->client_.setTimeout(this->timeout_);
@ -86,17 +94,18 @@ void HttpRequestComponent::send(const std::vector<HttpRequestResponseTrigger *>
ESP_LOGW(TAG, "HTTP Request failed; URL: %s; Error: %s; Duration: %u ms", this->url_.c_str(),
HTTPClient::errorToString(http_code).c_str(), duration);
this->status_set_warning();
return;
return RetryResult::RETRY;
}
if (http_code < 200 || http_code >= 300) {
ESP_LOGW(TAG, "HTTP Request failed; URL: %s; Code: %d; Duration: %u ms", this->url_.c_str(), http_code, duration);
this->status_set_warning();
return;
return RetryResult::DONE;
}
this->status_clear_warning();
ESP_LOGD(TAG, "HTTP Request completed; URL: %s; Code: %d; Duration: %u ms", this->url_.c_str(), http_code, duration);
return RetryResult::DONE;
}
#ifdef USE_ESP8266

View File

@ -45,6 +45,9 @@ class HttpRequestComponent : public Component {
void set_method(const char *method) { this->method_ = method; }
void set_useragent(const char *useragent) { this->useragent_ = useragent; }
void set_timeout(uint16_t timeout) { this->timeout_ = timeout; }
void set_retries(uint16_t retries) { this->retries_ = retries; }
void set_retry_delay(uint16_t retry_delay) { this->retry_delay_ = retry_delay; }
void set_retry_backoff_factor(float retry_backoff_factor) { this->retry_backoff_factor_ = retry_backoff_factor; }
void set_follow_redirects(bool follow_redirects) { this->follow_redirects_ = follow_redirects; }
void set_redirect_limit(uint16_t limit) { this->redirect_limit_ = limit; }
void set_body(const std::string &body) { this->body_ = body; }
@ -63,6 +66,9 @@ class HttpRequestComponent : public Component {
bool follow_redirects_;
uint16_t redirect_limit_;
uint16_t timeout_{5000};
uint16_t retries_{0};
uint16_t retry_delay_{1000};
float retry_backoff_factor_{1.0};
std::string body_;
std::list<Header> headers_;
#ifdef USE_ESP8266
@ -72,6 +78,7 @@ class HttpRequestComponent : public Component {
#endif
std::shared_ptr<WiFiClient> get_wifi_client_();
#endif
RetryResult send_(const std::vector<HttpRequestResponseTrigger *> &response_triggers, uint8_t attempt);
};
template<typename... Ts> class HttpRequestSendAction : public Action<Ts...> {
@ -92,6 +99,7 @@ template<typename... Ts> class HttpRequestSendAction : public Action<Ts...> {
void play(Ts... x) override {
this->parent_->set_url(this->url_.value(x...));
this->parent_->set_method(this->method_.value(x...));
this->parent_->set_body("");
if (this->body_.has_value()) {
this->parent_->set_body(this->body_.value(x...));
}
@ -114,7 +122,6 @@ template<typename... Ts> class HttpRequestSendAction : public Action<Ts...> {
this->parent_->set_headers(headers);
this->parent_->send(this->response_triggers_);
this->parent_->close();
this->parent_->set_body("");
}
protected:

View File

@ -87,6 +87,10 @@ mdns:
http_request:
useragent: esphome/device
timeout: 10s
retry:
count: 3
delay: 1s
backoff_factor: 1.5
mqtt:
broker: "192.168.178.84"