mirror of
https://github.com/esphome/esphome.git
synced 2025-01-08 13:51:43 +01:00
5b0fbbaada
* Replace std::move() with const references where possible * Fix formatting
143 lines
4.5 KiB
C++
143 lines
4.5 KiB
C++
#pragma once
|
|
|
|
#ifdef USE_ARDUINO
|
|
|
|
#include "esphome/components/json/json_util.h"
|
|
#include "esphome/core/automation.h"
|
|
#include "esphome/core/component.h"
|
|
#include "esphome/core/defines.h"
|
|
#include <list>
|
|
#include <map>
|
|
#include <utility>
|
|
#include <memory>
|
|
|
|
#ifdef USE_ESP32
|
|
#include <HTTPClient.h>
|
|
#endif
|
|
#ifdef USE_ESP8266
|
|
#include <ESP8266HTTPClient.h>
|
|
#ifdef USE_HTTP_REQUEST_ESP8266_HTTPS
|
|
#include <WiFiClientSecure.h>
|
|
#endif
|
|
#endif
|
|
|
|
namespace esphome {
|
|
namespace http_request {
|
|
|
|
struct Header {
|
|
const char *name;
|
|
const char *value;
|
|
};
|
|
|
|
class HttpRequestResponseTrigger;
|
|
|
|
class HttpRequestComponent : public Component {
|
|
public:
|
|
void dump_config() override;
|
|
float get_setup_priority() const override { return setup_priority::AFTER_WIFI; }
|
|
|
|
void set_url(std::string url);
|
|
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_body(const std::string &body) { this->body_ = body; }
|
|
void set_headers(std::list<Header> headers) { this->headers_ = std::move(headers); }
|
|
void send(const std::vector<HttpRequestResponseTrigger *> &response_triggers);
|
|
void close();
|
|
const char *get_string();
|
|
|
|
protected:
|
|
HTTPClient client_{};
|
|
std::string url_;
|
|
std::string last_url_;
|
|
const char *method_;
|
|
const char *useragent_{nullptr};
|
|
bool secure_;
|
|
uint16_t timeout_{5000};
|
|
std::string body_;
|
|
std::list<Header> headers_;
|
|
#ifdef USE_ESP8266
|
|
std::shared_ptr<WiFiClient> wifi_client_;
|
|
#ifdef USE_HTTP_REQUEST_ESP8266_HTTPS
|
|
std::shared_ptr<BearSSL::WiFiClientSecure> wifi_client_secure_;
|
|
#endif
|
|
std::shared_ptr<WiFiClient> get_wifi_client_();
|
|
#endif
|
|
};
|
|
|
|
template<typename... Ts> class HttpRequestSendAction : public Action<Ts...> {
|
|
public:
|
|
HttpRequestSendAction(HttpRequestComponent *parent) : parent_(parent) {}
|
|
TEMPLATABLE_VALUE(std::string, url)
|
|
TEMPLATABLE_VALUE(const char *, method)
|
|
TEMPLATABLE_VALUE(std::string, body)
|
|
TEMPLATABLE_VALUE(const char *, useragent)
|
|
TEMPLATABLE_VALUE(uint16_t, timeout)
|
|
|
|
void add_header(const char *key, TemplatableValue<const char *, Ts...> value) { this->headers_.insert({key, value}); }
|
|
|
|
void add_json(const char *key, TemplatableValue<std::string, Ts...> value) { this->json_.insert({key, value}); }
|
|
|
|
void set_json(std::function<void(Ts..., JsonObject &)> json_func) { this->json_func_ = json_func; }
|
|
|
|
void register_response_trigger(HttpRequestResponseTrigger *trigger) { this->response_triggers_.push_back(trigger); }
|
|
|
|
void play(Ts... x) override {
|
|
this->parent_->set_url(this->url_.value(x...));
|
|
this->parent_->set_method(this->method_.value(x...));
|
|
if (this->body_.has_value()) {
|
|
this->parent_->set_body(this->body_.value(x...));
|
|
}
|
|
if (!this->json_.empty()) {
|
|
auto f = std::bind(&HttpRequestSendAction<Ts...>::encode_json_, this, x..., std::placeholders::_1);
|
|
this->parent_->set_body(json::build_json(f));
|
|
}
|
|
if (this->json_func_ != nullptr) {
|
|
auto f = std::bind(&HttpRequestSendAction<Ts...>::encode_json_func_, this, x..., std::placeholders::_1);
|
|
this->parent_->set_body(json::build_json(f));
|
|
}
|
|
if (this->useragent_.has_value()) {
|
|
this->parent_->set_useragent(this->useragent_.value(x...));
|
|
}
|
|
if (this->timeout_.has_value()) {
|
|
this->parent_->set_timeout(this->timeout_.value(x...));
|
|
}
|
|
if (!this->headers_.empty()) {
|
|
std::list<Header> headers;
|
|
for (const auto &item : this->headers_) {
|
|
auto val = item.second;
|
|
Header header;
|
|
header.name = item.first;
|
|
header.value = val.value(x...);
|
|
headers.push_back(header);
|
|
}
|
|
this->parent_->set_headers(headers);
|
|
}
|
|
this->parent_->send(this->response_triggers_);
|
|
this->parent_->close();
|
|
}
|
|
|
|
protected:
|
|
void encode_json_(Ts... x, JsonObject &root) {
|
|
for (const auto &item : this->json_) {
|
|
auto val = item.second;
|
|
root[item.first] = val.value(x...);
|
|
}
|
|
}
|
|
void encode_json_func_(Ts... x, JsonObject &root) { this->json_func_(x..., root); }
|
|
HttpRequestComponent *parent_;
|
|
std::map<const char *, TemplatableValue<const char *, Ts...>> headers_{};
|
|
std::map<const char *, TemplatableValue<std::string, Ts...>> json_{};
|
|
std::function<void(Ts..., JsonObject &)> json_func_{nullptr};
|
|
std::vector<HttpRequestResponseTrigger *> response_triggers_;
|
|
};
|
|
|
|
class HttpRequestResponseTrigger : public Trigger<int> {
|
|
public:
|
|
void process(int status_code) { this->trigger(status_code); }
|
|
};
|
|
|
|
} // namespace http_request
|
|
} // namespace esphome
|
|
|
|
#endif // USE_ARDUINO
|