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