ESPHome  2022.6.2
http_request.h
Go to the documentation of this file.
1 #pragma once
2 
3 #ifdef USE_ARDUINO
4 
8 #include "esphome/core/defines.h"
9 #include <list>
10 #include <map>
11 #include <utility>
12 #include <memory>
13 
14 #ifdef USE_ESP32
15 #include <HTTPClient.h>
16 #endif
17 #ifdef USE_ESP8266
18 #include <ESP8266HTTPClient.h>
19 #ifdef USE_HTTP_REQUEST_ESP8266_HTTPS
20 #include <WiFiClientSecure.h>
21 #endif
22 #endif
23 
24 namespace esphome {
25 namespace http_request {
26 
27 struct Header {
28  const char *name;
29  const char *value;
30 };
31 
33 
35  public:
36  void dump_config() override;
37  float get_setup_priority() const override { return setup_priority::AFTER_WIFI; }
38 
39  void set_url(std::string url);
40  void set_method(const char *method) { this->method_ = method; }
41  void set_useragent(const char *useragent) { this->useragent_ = useragent; }
42  void set_timeout(uint16_t timeout) { this->timeout_ = timeout; }
43  void set_follow_redirects(bool follow_redirects) { this->follow_redirects_ = follow_redirects; }
44  void set_redirect_limit(uint16_t limit) { this->redirect_limit_ = limit; }
45  void set_body(const std::string &body) { this->body_ = body; }
46  void set_headers(std::list<Header> headers) { this->headers_ = std::move(headers); }
47  void send(const std::vector<HttpRequestResponseTrigger *> &response_triggers);
48  void close();
49  const char *get_string();
50 
51  protected:
52  HTTPClient client_{};
53  std::string url_;
54  std::string last_url_;
55  const char *method_;
56  const char *useragent_{nullptr};
57  bool secure_;
59  uint16_t redirect_limit_;
60  uint16_t timeout_{5000};
61  std::string body_;
62  std::list<Header> headers_;
63 #ifdef USE_ESP8266
64  std::shared_ptr<WiFiClient> wifi_client_;
65 #ifdef USE_HTTP_REQUEST_ESP8266_HTTPS
66  std::shared_ptr<BearSSL::WiFiClientSecure> wifi_client_secure_;
67 #endif
68  std::shared_ptr<WiFiClient> get_wifi_client_();
69 #endif
70 };
71 
72 template<typename... Ts> class HttpRequestSendAction : public Action<Ts...> {
73  public:
74  HttpRequestSendAction(HttpRequestComponent *parent) : parent_(parent) {}
75  TEMPLATABLE_VALUE(std::string, url)
76  TEMPLATABLE_VALUE(const char *, method)
77  TEMPLATABLE_VALUE(std::string, body)
78  TEMPLATABLE_VALUE(const char *, useragent)
79  TEMPLATABLE_VALUE(uint16_t, timeout)
80 
81  void add_header(const char *key, TemplatableValue<const char *, Ts...> value) { this->headers_.insert({key, value}); }
82 
83  void add_json(const char *key, TemplatableValue<std::string, Ts...> value) { this->json_.insert({key, value}); }
84 
85  void set_json(std::function<void(Ts..., JsonObject)> json_func) { this->json_func_ = json_func; }
86 
87  void register_response_trigger(HttpRequestResponseTrigger *trigger) { this->response_triggers_.push_back(trigger); }
88 
89  void play(Ts... x) override {
90  this->parent_->set_url(this->url_.value(x...));
91  this->parent_->set_method(this->method_.value(x...));
92  if (this->body_.has_value()) {
93  this->parent_->set_body(this->body_.value(x...));
94  }
95  if (!this->json_.empty()) {
96  auto f = std::bind(&HttpRequestSendAction<Ts...>::encode_json_, this, x..., std::placeholders::_1);
97  this->parent_->set_body(json::build_json(f));
98  }
99  if (this->json_func_ != nullptr) {
100  auto f = std::bind(&HttpRequestSendAction<Ts...>::encode_json_func_, this, x..., std::placeholders::_1);
101  this->parent_->set_body(json::build_json(f));
102  }
103  if (this->useragent_.has_value()) {
104  this->parent_->set_useragent(this->useragent_.value(x...));
105  }
106  if (this->timeout_.has_value()) {
107  this->parent_->set_timeout(this->timeout_.value(x...));
108  }
109  if (!this->headers_.empty()) {
110  std::list<Header> headers;
111  for (const auto &item : this->headers_) {
112  auto val = item.second;
113  Header header;
114  header.name = item.first;
115  header.value = val.value(x...);
116  headers.push_back(header);
117  }
118  this->parent_->set_headers(headers);
119  }
120  this->parent_->send(this->response_triggers_);
121  this->parent_->close();
122  }
123 
124  protected:
125  void encode_json_(Ts... x, JsonObject root) {
126  for (const auto &item : this->json_) {
127  auto val = item.second;
128  root[item.first] = val.value(x...);
129  }
130  }
131  void encode_json_func_(Ts... x, JsonObject root) { this->json_func_(x..., root); }
133  std::map<const char *, TemplatableValue<const char *, Ts...>> headers_{};
134  std::map<const char *, TemplatableValue<std::string, Ts...>> json_{};
135  std::function<void(Ts..., JsonObject)> json_func_{nullptr};
136  std::vector<HttpRequestResponseTrigger *> response_triggers_;
137 };
138 
139 class HttpRequestResponseTrigger : public Trigger<int> {
140  public:
141  void process(int status_code) { this->trigger(status_code); }
142 };
143 
144 } // namespace http_request
145 } // namespace esphome
146 
147 #endif // USE_ARDUINO
void set_json(std::function< void(Ts..., JsonObject)> json_func)
Definition: http_request.h:85
const float AFTER_WIFI
For components that should be initialized after WiFi is connected.
Definition: component.cpp:24
void set_follow_redirects(bool follow_redirects)
Definition: http_request.h:43
void set_useragent(const char *useragent)
Definition: http_request.h:41
void add_json(const char *key, TemplatableValue< std::string, Ts... > value)
Definition: http_request.h:83
std::shared_ptr< BearSSL::WiFiClientSecure > wifi_client_secure_
Definition: http_request.h:66
void set_headers(std::list< Header > headers)
Definition: http_request.h:46
void set_body(const std::string &body)
Definition: http_request.h:45
void encode_json_func_(Ts... x, JsonObject root)
Definition: http_request.h:131
std::vector< HttpRequestResponseTrigger * > response_triggers_
Definition: http_request.h:136
std::string build_json(const json_build_t &f)
Build a JSON string with the provided json build function.
Definition: json_util.cpp:18
HttpRequestSendAction(HttpRequestComponent *parent)
Definition: http_request.h:74
Definition: a4988.cpp:4
uint32_t val
Definition: datatypes.h:85
void register_response_trigger(HttpRequestResponseTrigger *trigger)
Definition: http_request.h:87
void encode_json_(Ts... x, JsonObject root)
Definition: http_request.h:125
std::shared_ptr< WiFiClient > wifi_client_
Definition: http_request.h:64